Commit Diff


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
@@ -14,12 +14,20 @@
  * 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
@@ -33,7 +41,7 @@ usage(void)
 static int
 validate_email_addr(const char *addr)
 {
-	return 0;
+	return 1;
 }
 
 static char *
@@ -43,20 +51,70 @@ set_default_fromaddr(void)
 }
 
 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;
 
@@ -83,26 +141,32 @@ main(int argc, char *argv[])
 	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 =
@@ -115,6 +179,7 @@ done:
 		if (error == NULL)
 			error = close_err;
 	}
+	free(cwd);
 	if (error) {
 		fflush(stdout);
 		fprintf(stderr, "%s: %s\n", getprogname(), error->msg);