contrib/chg/chg.c
changeset 28260 0a17cfbe5429
parent 28237 a3d73e069f8d
child 28261 2ab59ac06b76
--- a/contrib/chg/chg.c	Wed Feb 24 13:20:06 2016 +0000
+++ b/contrib/chg/chg.c	Fri Feb 26 14:17:59 2016 +0000
@@ -448,11 +448,51 @@
 	abortmsg("failed to prepare pager (errno = %d)", errno);
 }
 
+/*
+ * Test whether the command is unsupported or not. This is not designed to
+ * cover all cases. But it's fast, does not depend on the server and does
+ * not return false positives.
+ */
+static int isunsupported(int argc, const char *argv[])
+{
+	enum {
+		SERVE = 1,
+		DAEMON = 2,
+		SERVEDAEMON = SERVE | DAEMON,
+		TIME = 4,
+	};
+	unsigned int state = 0;
+	int i;
+	for (i = 0; i < argc; ++i) {
+		if (strcmp(argv[i], "--") == 0)
+			break;
+		if (i == 0 && strcmp("serve", argv[i]) == 0)
+			state |= SERVE;
+		else if (strcmp("-d", argv[i]) == 0 ||
+			 strcmp("--daemon", argv[i]) == 0)
+			state |= DAEMON;
+		else if (strcmp("--time", argv[i]) == 0)
+			state |= TIME;
+	}
+	return (state & TIME) == TIME ||
+	       (state & SERVEDAEMON) == SERVEDAEMON;
+}
+
+static void execoriginalhg(const char *argv[])
+{
+	debugmsg("execute original hg");
+	if (execvp(gethgcmd(), (char **)argv) < 0)
+		abortmsg("failed to exec original hg (errno = %d)", errno);
+}
+
 int main(int argc, const char *argv[], const char *envp[])
 {
 	if (getenv("CHGDEBUG"))
 		enabledebugmsg();
 
+	if (isunsupported(argc - 1, argv + 1))
+		execoriginalhg(argv);
+
 	struct cmdserveropts opts;
 	initcmdserveropts(&opts);
 	setcmdserveropts(&opts);