Source

pcw / pcw.c

Diff from to

File pcw.c

 #include "config.h" // for CMD
 
 // fairly arbitray values...feel free to change
-#define PATH_MAX    1024
-#define CMD_MAX     1024
-#define MAX_ARGS    64
+#define PATH_MAX    256
 #define MAX_OPENFD  4
-#define MAX_WATCH   512
 
-int evq;
-int wins[MAX_WATCH] = {0};
-char paths[MAX_WATCH][PATH_MAX] = {{0}};
-char *nick = "";
+struct watch {
+	int wd;
+	pid_t pid;
+	char path[PATH_MAX];
+	struct watch *next;
+};
 
-void win(int wd)
+static struct watch *watches = NULL;
+static int evq;
+static char *nick = "";
+
+void win(struct watch *w)
 {
+	int fd = 0;
 	char out[PATH_MAX], in[PATH_MAX], path[PATH_MAX], channel[32];
 	char *cmd[] = CMD; // from config.h
+	struct stat st;
 
-	if (wins[wd])
+	if (w->pid)
 		return;
 
-	strcpy(path, paths[wd]); // stupid basename messing with my strings
-	sprintf(channel, "%s> ", basename(path));
-	sprintf(out, "%s/out", paths[wd]);
-	sprintf(in,  "%s/in",  paths[wd]);
+	sprintf(out, "%s/out", w->path);
+	sprintf(in,  "%s/in",  w->path);
 
-	if ((wins[wd] = fork()) == 0) {
+	// open() to see if ii has the fifo open for reading
+	if (stat(out, &st) < 0 || stat(in, &st) < 0 || (fd = open(in, O_WRONLY | O_NONBLOCK)) < 0)
+		return;
+
+	close(fd);
+	strcpy(path, w->path); // stupid basename messing with my strings
+	snprintf(channel, sizeof(channel), "%s> ", basename(path));
+
+	if ((w->pid = fork()) == 0) {
 		execvp(cmd[0], cmd);
 		err(1, "failed on execvp %s", cmd[0]);
 	}
 
 int add_dir(const char *fpath, const struct stat *sb, int typeflag)
 {
-	int wd, fd;
-	char out[PATH_MAX], in[PATH_MAX];
-	struct stat st;
+	int wd;
+	struct watch *w;
 
 	if (!(typeflag & FTW_D))
 		return 0;
 		return 0;
 	}
 
-	if (paths[wd][0] == '\0') {
-		strcpy(paths[wd], fpath);
-		sprintf(out, "%s/out", fpath);
-		sprintf(in,  "%s/in",  fpath);
-		// open() to see if ii has the fifo open for reading
-		if (stat(out, &st) == 0 && stat(in, &st) == 0 && (fd = open(in, O_WRONLY | O_NONBLOCK)) != -1) {
-			close(fd);
-			win(wd);
-		}
-	}
+	for (w = watches; w; w = w->next)
+		if (w->wd == wd)
+			return 0;
+
+	if ((w = calloc(1, sizeof(struct watch))) == NULL)
+		err(1, "error on calloc");
+
+	w->next = watches;
+	watches = w;
+
+	w->wd = wd;
+	strcpy(w->path, fpath);
+
+	win(w);
 
 	return 0;
 }
 
-int find(int *haystack, int needle, int len)
-{
-	int i;
+void sigusr(int unused) {
+	struct watch *w;
 
-	for (i = 0; i < len; i++)
-		if (haystack[i] == needle)
-			return i;
-
-	return -1;
-}
-
-void sigusr(int unused) {
-	int i, fd;
-	char out[PATH_MAX], in[PATH_MAX];
-	struct stat st;
-
-	for (i = 0; i < MAX_WATCH; i++) {
-		if (paths[i][0] == '\0')
-			continue;
-		sprintf(out, "%s/out", paths[i]);
-		sprintf(in,  "%s/in",  paths[i]);
-		if (stat(out, &st) == 0 && stat(in, &st) == 0 && (fd = open(in, O_WRONLY | O_NONBLOCK)) != -1) {
-			close(fd);
-			win(i);
-		}
-	}
+	for (w = watches; w; w = w->next)
+		win(w);
 }
 
 void sigchld(int unused)
 {
 	pid_t pid;
-	int wd;
+	struct watch *w;
 
-	while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
-		if ((wd = find(wins, pid, MAX_WATCH)) > -1)
-			wins[wd] = 0;
-	}
+	while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
+		for (w = watches; w; w = w->next)
+			if (w->pid == pid)
+				w->pid = 0;
 }
+
 void usage(void)
 {
 	fprintf(stderr, "Usage: pcw [-n nick] [-v] dir\n");
 	int len, i;
 	struct inotify_event *cur;
 	struct stat st;
+	struct watch *w;
 
 	for (i = 1; i < argc; i++) {
 		if (argv[i][0] != '-')
 
 			if (cur->mask & (IN_CREATE | IN_ISDIR))
 				ftw(argv[i], add_dir, MAX_OPENFD);
-			if (cur->mask & (IN_CREATE | IN_MODIFY) && !strcmp(cur->name, "out"))
-				win(cur->wd);
+			if (cur->mask & (IN_CREATE | IN_MODIFY) && !strcmp(cur->name, "out")) {
+				for (w = watches; w; w = w->next) {
+					if (w->wd == cur->wd) {
+						win(w);
+						break;
+					}
+				}
+			}
 		}
 	}