aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fossil/fossil.c
diff options
context:
space:
mode:
authorDavid du Colombier <0intro@gmail.com>2013-09-23 23:00:39 +0200
committerDavid du Colombier <0intro@gmail.com>2013-09-23 23:00:39 +0200
commit6f4d00ee45693290fae042b27536b54f77b96acd (patch)
tree60ad31bf16ed2000661c02345dd2a63851588a5d /src/cmd/fossil/fossil.c
parentfea86f063930ea187f1c77e93207ac8d39125520 (diff)
downloadplan9port-6f4d00ee45693290fae042b27536b54f77b96acd.tar.gz
plan9port-6f4d00ee45693290fae042b27536b54f77b96acd.tar.bz2
plan9port-6f4d00ee45693290fae042b27536b54f77b96acd.zip
fossil: import from plan 9
R=rsc https://codereview.appspot.com/7988047
Diffstat (limited to 'src/cmd/fossil/fossil.c')
-rw-r--r--src/cmd/fossil/fossil.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/cmd/fossil/fossil.c b/src/cmd/fossil/fossil.c
new file mode 100644
index 00000000..8ef68080
--- /dev/null
+++ b/src/cmd/fossil/fossil.c
@@ -0,0 +1,143 @@
+#include "stdinc.h"
+#include <ctype.h>
+
+#include "9.h"
+
+int Dflag;
+int mempcnt; /* for 9fsys.c */
+char* none = "none";
+char* foptname = "/none/such";
+
+static void
+usage(void)
+{
+ fprint(2, "usage: %s [-Dt] [-c cmd] [-f partition] [-m %%]\n", argv0);
+ exits("usage");
+}
+
+static void
+readCmdPart(char *file, char ***pcmd, int *pncmd)
+{
+ char buf[1024+1], *f[1024];
+ char tbuf[1024];
+ int nf;
+ int i, fd, n;
+ char **cmd, *p;
+ int ncmd;
+
+ cmd = *pcmd;
+ ncmd = *pncmd;
+
+ if((fd = open(file, OREAD)) < 0)
+ sysfatal("open %s: %r", file);
+ if(seek(fd, 127*1024, 0) != 127*1024)
+ sysfatal("seek %s 127kB: %r", file);
+ n = readn(fd, buf, sizeof buf-1);
+ if(n == 0)
+ sysfatal("short read of %s at 127kB", file);
+ if(n < 0)
+ sysfatal("read %s: %r", file);
+ buf[n] = 0;
+ if(memcmp(buf, "fossil config\n", 6+1+6+1) != 0)
+ sysfatal("bad config magic in %s", file);
+ nf = getfields(buf+6+1+6+1, f, nelem(f), 1, "\n");
+ for(i=0; i<nf; i++){
+ if(f[i][0] == '#')
+ continue;
+ cmd = vtMemRealloc(cmd, (ncmd+1)*sizeof(char*));
+ /* expand argument '*' to mean current file */
+ if((p = strchr(f[i], '*')) && (p==f[i]||isspace(p[-1])) && (p[1]==0||isspace(p[1]))){
+ memmove(tbuf, f[i], p-f[i]);
+ strecpy(tbuf+(p-f[i]), tbuf+sizeof tbuf, file);
+ strecpy(tbuf+strlen(tbuf), tbuf+sizeof tbuf, p+1);
+ f[i] = tbuf;
+ }
+ cmd[ncmd++] = vtStrDup(f[i]);
+ }
+ close(fd);
+ *pcmd = cmd;
+ *pncmd = ncmd;
+}
+
+void
+main(int argc, char* argv[])
+{
+ char **cmd, *p;
+ int i, ncmd, tflag;
+
+ fmtinstall('D', dirfmt);
+ fmtinstall('F', fcallfmt);
+ fmtinstall('M', dirmodefmt);
+ quotefmtinstall();
+
+ /*
+ * Insulate from the invoker's environment.
+ */
+ if(rfork(RFREND|RFNOTEG|RFNAMEG) < 0)
+ sysfatal("rfork: %r");
+
+ close(0);
+ open("/dev/null", OREAD);
+ close(1);
+ open("/dev/null", OWRITE);
+
+ cmd = nil;
+ ncmd = tflag = 0;
+
+ vtAttach();
+
+ ARGBEGIN{
+ case '?':
+ default:
+ usage();
+ break;
+ case 'c':
+ p = EARGF(usage());
+ currfsysname = p;
+ cmd = vtMemRealloc(cmd, (ncmd+1)*sizeof(char*));
+ cmd[ncmd++] = p;
+ break;
+ case 'D':
+ Dflag ^= 1;
+ break;
+ case 'f':
+ p = EARGF(usage());
+ currfsysname = foptname = p;
+ readCmdPart(p, &cmd, &ncmd);
+ break;
+ case 'm':
+ mempcnt = atoi(EARGF(usage()));
+ if(mempcnt <= 0 || mempcnt >= 100)
+ usage();
+ break;
+ case 't':
+ tflag = 1;
+ break;
+ }ARGEND
+ if(argc != 0)
+ usage();
+
+ consInit();
+ cliInit();
+ msgInit();
+ conInit();
+ cmdInit();
+ fsysInit();
+ exclInit();
+ fidInit();
+
+ srvInit();
+ lstnInit();
+ usersInit();
+
+ for(i = 0; i < ncmd; i++)
+ if(cliExec(cmd[i]) == 0)
+ fprint(2, "%s: %R\n", cmd[i]);
+ vtMemFree(cmd);
+
+ if(tflag && consTTY() == 0)
+ consPrint("%s\n", vtGetError());
+
+ vtDetach();
+ exits(0);
+}