commit - c6d588b78684a2992b61c72b64f1bb3bab4b560c
commit + dd669d1824c1e2077bc147b91460ca4209621ced
blob - 4746965b3fd5d0df1e8a79c035b8b42c798b661e
blob + cdc23983f6af5f4cf642e738040bcb424ce25a4b
--- gotd/libexec/got-notify-email/got-notify-email.c
+++ gotd/libexec/got-notify-email/got-notify-email.c
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/queue.h>
+
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <getopt.h>
+#include <sha1.h>
+#include <sha2.h>
+#include <unistd.h>
#include "got_error.h"
#include "got_repository.h"
+#include "got_object.h"
+#include "got_reference.h"
__dead static void
static int
validate_email_addr(const char *addr)
{
- return 0;
+ return 1;
}
static char *
}
static const struct got_error *
-notify(struct got_repository *repo, const char *fromaddr,
+send_notifications(struct got_repository *repo, const char *fromaddr,
const char *recipient, char *replytoaddr, int shortlog,
int with_diff)
{
- return got_error(GOT_ERR_NOT_IMPL);
+ const struct got_error *err;
+ char *line = NULL, *space = NULL;
+ size_t linesize = 0;
+ ssize_t linelen;
+ struct got_object_id *id = NULL;
+ struct got_reference *ref = NULL;
+ const char *refname;
+ int have_line = 0;
+
+ while ((linelen = getline(&line, &linesize, stdin)) != -1) {
+ have_line = 1;
+
+ while (linelen > 0 && line[linelen - 1] == '\n') {
+ line[linelen - 1] = '\0';
+ linelen--;
+ }
+
+ space = strchr(line, ' ');
+ if (space == NULL) {
+ err = got_error_fmt(GOT_ERR_BAD_REF_NAME,
+ "no separator found between commit ID and "
+ "reference name: %s", line);
+ goto done;
+ }
+
+ *space = '\0';
+
+ refname = space + 1;
+ err = got_ref_open(&ref, repo, refname, 0);
+ if (err)
+ goto done;
+
+ err = got_object_resolve_id_str(&id, repo, line);
+ if (err)
+ goto done;
+
+ free(id);
+ id = NULL;
+ got_ref_close(ref);
+ ref = NULL;
+ }
+
+ if (!have_line)
+ err = got_error_fmt(GOT_ERR_EOF,
+ "reading 'commit reference-name' pairs from stdin");
+done:
+ free(line);
+ free(id);
+ if (ref)
+ got_ref_close(ref);
+ return err;
}
int
main(int argc, char *argv[])
{
- const struct got_error *error;
+ const struct got_error *error = NULL;
struct got_repository *repo = NULL;
int ch, *pack_fds = NULL;
- char *repo_path = NULL, *fromaddr = NULL;
+ char *cwd = NULL, *repo_path = NULL, *fromaddr = NULL;
char *recipient = NULL, *replytoaddr = NULL;
int shortlog = 0, with_diff = 0;
argc -= optind;
argv += optind;
- if (argc != 2)
+ if (argc != 1)
usage();
- recipient = argv[1];
-
+ recipient = argv[0];
if (!validate_email_addr(recipient))
goto done;
if (fromaddr == NULL)
fromaddr = set_default_fromaddr();
+ if (repo_path == NULL) {
+ cwd = getcwd(NULL, 0);
+ if (cwd == NULL)
+ error = got_error_from_errno("getcwd");
+ repo_path = cwd;
+ }
error = got_repo_pack_fds_open(&pack_fds);
if (error != NULL)
goto done;
+
error = got_repo_open(&repo, repo_path, NULL, pack_fds);
if (error)
goto done;
- error = notify(repo, fromaddr, recipient, replytoaddr, shortlog,
- with_diff);
+ error = send_notifications(repo, fromaddr, recipient, replytoaddr,
+ shortlog, with_diff);
done:
if (pack_fds) {
const struct got_error *pack_err =
if (error == NULL)
error = close_err;
}
+ free(cwd);
if (error) {
fflush(stdout);
fprintf(stderr, "%s: %s\n", getprogname(), error->msg);