예제 #1
0
파일: cbsd_fwatch.c 프로젝트: fmendezp/cbsd
int
main(int argc, char **argv)
{
	int		kq;
	struct kevent  *e, kev_r;
	int		n         , i;
	int		optcode = 0;
	int		option_index = 0;
	struct timespec	tv;
	FILE           *fp;
	char           *watchfile = NULL;
	int		timeout = 0;

	struct option	long_options[] = {
		{"file", required_argument, 0, C_FILE},
		{"timeout", required_argument, 0, C_TIMEOUT},
		/* End of options marker */
		{0, 0, 0, 0}
	};

	if (argc < 2) {
		cbsd_fwatch_usage();
		return 0;
	}

	while (TRUE) {
		optcode = getopt_long_only(argc, argv, "", long_options, &option_index);
		if (optcode == -1)
			break;
		switch (optcode) {
		case C_FILE:
			watchfile = malloc(strlen(optarg) + 1);
			memset(watchfile, 0, strlen(optarg) + 1);
			strcpy(watchfile, optarg);
			break;
		case C_TIMEOUT:
			timeout = atoi(optarg);
			break;
		}
	} //while

	//zero for getopt *variables for next execute
	optarg = NULL;
	optind = 0;
	optopt = 0;
	opterr = 0;
	optreset = 0;

	if (!watchfile) {
		cbsd_fwatch_usage();
		return 1;
	}
	fp = fopen(watchfile, "r");

	if (!fp) {
		printf("Can't open file for mon: %s\n", watchfile);
		free(watchfile);
		return 1;
	}
	kq = kqueue();

	if (kq == -1) {
		fclose(fp);
		free(watchfile);
		printf("kqueue error");
		return 1;
	}
	e = malloc(argc * sizeof(struct kevent));

	if (e == NULL) {
		fclose(fp);
		free(watchfile);
		printf("malloc");
		return 1;
	}
	i = 0;

	//todo:multiple file alteration
	EV_SET(e + i, (*fp)._file, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE | NOTE_WRITE, 0, NULL);

	if (kevent(kq, e + i, 1, &kev_r, 0, NULL) == -1)
		printf("kevent");
	else
		i++;

	tv.tv_sec = timeout;
	tv.tv_nsec = 0;
	//tv.tv_usec = 0;

	while (i > 0) {
		if (kev_r.fflags & NOTE_WRITE) {
			printf("updated\n");
		} else if (kev_r.fflags & NOTE_DELETE) {
			printf("deleted\n");
		}
		if (timeout == 0)
			n = kevent(kq, NULL, 0, e, i, NULL);
		else
			n = kevent(kq, NULL, 0, e, i, &tv);
		if (n == -1) {
			fclose(fp);
			printf("kevent");
			free(e);
			free(watchfile);
			return 1;
		}
		i--;
	}

	free(e);
	free(watchfile);
	fclose(fp);
	return (EX_OK);
}
예제 #2
0
파일: cbsd_fwatch.c 프로젝트: cbsd/cbsd
int
cbsd_fwatchcmd(int argc, char *argv[])
{
	int fd, kq, nev;
	struct kevent ev;

	int optcode = 0;
	int option_index = 0;
	struct timespec tv;
	char *watchfile = NULL;
	int timeout = 10;
	char cmd[10];

	struct option   long_options[] = {
		{ "file", required_argument, 0, C_FILE },
		{ "timeout", required_argument, 0, C_TIMEOUT },
		/* End of options marker */
		{ 0, 0, 0, 0 }
	};

	if (argc < 2) {
		cbsd_fwatch_usage();
		return 0;
	}

	while (TRUE) {
		optcode = getopt_long_only(argc, argv, "", long_options, &option_index);
		if (optcode == -1)
			break;
		switch (optcode) {
			case C_FILE:
				watchfile = malloc(strlen(optarg) + 1);
				memset(watchfile, 0, strlen(optarg) + 1);
				strcpy(watchfile, optarg);
			break;
			case C_TIMEOUT:
				timeout = atoi(optarg);
			break;
		}
	} //while

	//zero for getopt *variables for next execute
	optarg = NULL;
	optind = 0;
	optopt = 0;
	opterr = 0;
	optreset = 0;

	if (!watchfile) {
		cbsd_fwatch_usage();
		return 1;
	}

	if ((fd = open(watchfile, O_RDONLY)) == -1) {
		out2fmt_flush("Cannot open: %s\n", watchfile);
		ckfree(watchfile);
		return(1);
	}

	if ((kq = kqueue()) == -1) {
		out2fmt_flush("Cannot create kqueue\n");
		close(fd);
		ckfree(watchfile);
		return 1;
	}

	EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
		NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
		NOTE_RENAME|NOTE_REVOKE, 0, 0);

	if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) {
		out2fmt_flush("kevent\n");
		close(fd);
		ckfree(watchfile);
		close(kq);
		return 1;
	}

	tv.tv_sec = timeout;
	tv.tv_nsec = 0;

	memset(cmd,0,sizeof(cmd));

	if (timeout == 0)
		nev = kevent(kq, NULL, 0, &ev, 1, NULL);
	else
		nev = kevent(kq, NULL, 0, &ev, 1, &tv);

	if (nev == -1) {
		out2fmt_flush("kevent\n");
		close(fd);
		ckfree(watchfile);
		close(kq);
		return 1;
	}

	close(kq);
	close(fd);

	if (nev != 0) {
		if (ev.fflags & NOTE_DELETE) {
			out2fmt_flush("deleted\n");
			ev.fflags &= ~NOTE_DELETE;
		}

		if (ev.fflags & NOTE_WRITE) {
			out2fmt_flush("written\n");
			ev.fflags &= ~NOTE_WRITE;
		}

		if (ev.fflags & NOTE_EXTEND) {
			out2fmt_flush("extended\n");
			ev.fflags &= ~NOTE_EXTEND;
		}

		if (ev.fflags & NOTE_ATTRIB) {
			out2fmt_flush("chmod/chown/utimes\n");
			ev.fflags &= ~NOTE_ATTRIB;
		}

		if (ev.fflags & NOTE_LINK) {
			out2fmt_flush("hardlinked\n");
			ev.fflags &= ~NOTE_LINK;
		}

		if (ev.fflags & NOTE_RENAME) {
			out2fmt_flush("renamed\n");
			ev.fflags &= ~NOTE_RENAME;
		}

		if (ev.fflags & NOTE_REVOKE) {
			out2fmt_flush("revoked\n");
			ev.fflags &= ~NOTE_REVOKE;
		}
	}
	
	ckfree(watchfile);
	return 0;
}