⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		mode &= ~04000;	gid = -1;	if (gr == NULL || strcmp(group, gr->gr_name) != 0) {		if ((*group == ':' && (getgrgid(gid = atoi(group + 1)) == NULL))		   || ((gr = getgrnam(group)) == NULL)) {			if (mode & 02000) {				note("%s:%s: unknown group", host, group);				mode &= ~02000;			}		} else			gid = gr->gr_gid;	} else		gid = gr->gr_gid;	if (userid && gid >= 0) {		if (gr) for (i = 0; gr->gr_mem[i] != NULL; i++)			if (!(strcmp(user, gr->gr_mem[i])))				goto ok;		mode &= ~02000;		gid = -1;	}ok:	if (fd != -1 && fchown(fd, uid, gid) < 0 || chown(file, uid, gid) < 0)		note("%s: %s chown: %s", host, file, strerror(errno));	else if (mode & 07000 &&	   (fd != -1 && fchmod(fd, mode) < 0 || chmod(file, mode) < 0))		note("%s: %s chmod: %s", host, file, strerror(errno));	return(0);}/* * Check for files on the machine being updated that are not on the master * machine and remove them. */static voidrmchk(opts)	int opts;{	register char *cp, *s;	struct stat stb;	if (debug)		printf("rmchk()\n");	/*	 * Tell the remote to clean the files from the last directory sent.	 */	(void) sprintf(buf, "C%o\n", opts & VERIFY);	if (debug)		printf("buf = %s", buf);	(void) write(rem, buf, strlen(buf));	if (response() < 0)		return;	for (;;) {		cp = s = buf;		do {			if (read(rem, cp, 1) != 1)				lostconn(0);		} while (*cp++ != '\n' && cp < &buf[BUFSIZ]);		switch (*s++) {		case 'Q': /* Query if file should be removed */			/*			 * Return the following codes to remove query.			 * N\n -- file exists - DON'T remove.			 * Y\n -- file doesn't exist - REMOVE.			 */			*--cp = '\0';			(void) sprintf(tp, "/%s", s);			if (debug)				printf("check %s\n", target);			if (except(target))				(void) write(rem, "N\n", 2);			else if (lstat(target, &stb) < 0)				(void) write(rem, "Y\n", 2);			else				(void) write(rem, "N\n", 2);			break;		case '\0':			*--cp = '\0';			if (*s != '\0')				log(lfp, "%s\n", s);			break;		case 'E':			*tp = '\0';			ack();			return;		case '\1':		case '\2':			nerrs++;			if (*s != '\n') {				if (!iamremote) {					fflush(stdout);					(void) write(2, s, cp - s);				}				if (lfp != NULL)					(void) fwrite(s, 1, cp - s, lfp);			}			if (buf[0] == '\2')				lostconn(0);			break;		default:			error("rmchk: unexpected response '%s'\n", buf);			err();		}	}}/* * Check the current directory (initialized by the 'T' command to server()) * for extraneous files and remove them. */static voidclean(cp)	register char *cp;{	DIR *d;	register struct direct *dp;	struct stat stb;	char *otp;	int len, opts;	opts = 0;	while (*cp >= '0' && *cp <= '7')		opts = (opts << 3) | (*cp++ - '0');	if (*cp != '\0') {		error("clean: options not delimited\n");		return;	}	if ((d = opendir(target)) == NULL) {		error("%s:%s: %s\n", host, target, strerror(errno));		return;	}	ack();	otp = tp;	len = tp - target;	while (dp = readdir(d)) {		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))			continue;		if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {			error("%s:%s/%s: Name too long\n",				host, target, dp->d_name);			continue;		}		tp = otp;		*tp++ = '/';		cp = dp->d_name;;		while (*tp++ = *cp++)			;		tp--;		if (lstat(target, &stb) < 0) {			error("%s:%s: %s\n", host, target, strerror(errno));			continue;		}		(void) sprintf(buf, "Q%s\n", dp->d_name);		(void) write(rem, buf, strlen(buf));		cp = buf;		do {			if (read(rem, cp, 1) != 1)				cleanup(0);		} while (*cp++ != '\n' && cp < &buf[BUFSIZ]);		*--cp = '\0';		cp = buf;		if (*cp != 'Y')			continue;		if (opts & VERIFY) {			cp = buf;			*cp++ = '\0';			(void) sprintf(cp, "need to remove: %s\n", target);			(void) write(rem, buf, strlen(cp) + 1);		} else			removeit(&stb);	}	closedir(d);	(void) write(rem, "E\n", 2);	(void) response();	tp = otp;	*tp = '\0';}/* * Remove a file or directory (recursively) and send back an acknowledge * or an error message. */static voidremoveit(stp)	struct stat *stp;{	DIR *d;	struct direct *dp;	register char *cp;	struct stat stb;	char *otp;	int len;	switch (stp->st_mode & S_IFMT) {	case S_IFREG:	case S_IFLNK:		if (unlink(target) < 0)			goto bad;		goto removed;	case S_IFDIR:		break;	default:		error("%s:%s: not a plain file\n", host, target);		return;	}	if ((d = opendir(target)) == NULL)		goto bad;	otp = tp;	len = tp - target;	while (dp = readdir(d)) {		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))			continue;		if (len + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {			error("%s:%s/%s: Name too long\n",				host, target, dp->d_name);			continue;		}		tp = otp;		*tp++ = '/';		cp = dp->d_name;;		while (*tp++ = *cp++)			;		tp--;		if (lstat(target, &stb) < 0) {			error("%s:%s: %s\n", host, target, strerror(errno));			continue;		}		removeit(&stb);	}	closedir(d);	tp = otp;	*tp = '\0';	if (rmdir(target) < 0) {bad:		error("%s:%s: %s\n", host, target, strerror(errno));		return;	}removed:	cp = buf;	*cp++ = '\0';	(void) sprintf(cp, "removed %s\n", target);	(void) write(rem, buf, strlen(cp) + 1);}/* * Execute a shell command to handle special cases. */static voiddospecial(cmd)	char *cmd;{	int fd[2], status, pid, i;	register char *cp, *s;	char sbuf[BUFSIZ];	extern int userid, groupid;	if (pipe(fd) < 0) {		error("%s\n", strerror(errno));		return;	}	if ((pid = fork()) == 0) {		/*		 * Return everything the shell commands print.		 */		(void) close(0);		(void) close(1);		(void) close(2);		(void) open(_PATH_DEVNULL, O_RDONLY);		(void) dup(fd[1]);		(void) dup(fd[1]);		(void) close(fd[0]);		(void) close(fd[1]);		setgid(groupid);		setuid(userid);		execl(_PATH_BSHELL, "sh", "-c", cmd, 0);		_exit(127);	}	(void) close(fd[1]);	s = sbuf;	*s++ = '\0';	while ((i = read(fd[0], buf, sizeof(buf))) > 0) {		cp = buf;		do {			*s++ = *cp++;			if (cp[-1] != '\n') {				if (s < &sbuf[sizeof(sbuf)-1])					continue;				*s++ = '\n';			}			/*			 * Throw away blank lines.			 */			if (s == &sbuf[2]) {				s--;				continue;			}			(void) write(rem, sbuf, s - sbuf);			s = &sbuf[1];		} while (--i);	}	if (s > &sbuf[1]) {		*s++ = '\n';		(void) write(rem, sbuf, s - sbuf);	}	while ((i = wait(&status)) != pid && i != -1)		;	if (i == -1)		status = -1;	(void) close(fd[0]);	if (status)		error("shell returned %d\n", status);	else		ack();}#if __STDC__#include <stdarg.h>#else#include <varargs.h>#endifvoid#if __STDC__log(FILE *fp, const char *fmt, ...)#elselog(fp, fmt, va_alist)	FILE *fp;	char *fmt;        va_dcl#endif{	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	/* Print changes locally if not quiet mode */	if (!qflag)		(void)vprintf(fmt, ap);	/* Save changes (for mailing) if really updating files */	if (!(options & VERIFY) && fp != NULL)		(void)vfprintf(fp, fmt, ap);	va_end(ap);}void#if __STDC__error(const char *fmt, ...)#elseerror(fmt, va_alist)	char *fmt;        va_dcl#endif{	static FILE *fp;	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	++nerrs;	if (!fp && !(fp = fdopen(rem, "w")))		return;	if (iamremote) {		(void)fprintf(fp, "%crdist: ", 0x01);		(void)vfprintf(fp, fmt, ap);		fflush(fp);	}	else {		fflush(stdout);		(void)fprintf(stderr, "rdist: ");		(void)vfprintf(stderr, fmt, ap);		fflush(stderr);	}	if (lfp != NULL) {		(void)fprintf(lfp, "rdist: ");		(void)vfprintf(lfp, fmt, ap);		fflush(lfp);	}	va_end(ap);}void#if __STDC__fatal(const char *fmt, ...)#elsefatal(fmt, va_alist)	char *fmt;        va_dcl#endif{	static FILE *fp;	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	++nerrs;	if (!fp && !(fp = fdopen(rem, "w")))		return;	if (iamremote) {		(void)fprintf(fp, "%crdist: ", 0x02);		(void)vfprintf(fp, fmt, ap);		fflush(fp);	}	else {		fflush(stdout);		(void)fprintf(stderr, "rdist: ");		(void)vfprintf(stderr, fmt, ap);		fflush(stderr);	}	if (lfp != NULL) {		(void)fprintf(lfp, "rdist: ");		(void)vfprintf(lfp, fmt, ap);		fflush(lfp);	}	cleanup(0);}static intresponse(){	char *cp, *s;	char resp[BUFSIZ];	if (debug)		printf("response()\n");	cp = s = resp;	do {		if (read(rem, cp, 1) != 1)			lostconn(0);	} while (*cp++ != '\n' && cp < &resp[BUFSIZ]);	switch (*s++) {	case '\0':		*--cp = '\0';		if (*s != '\0') {			log(lfp, "%s\n", s);			return(1);		}		return(0);	case '\3':		*--cp = '\0';		log(lfp, "Note: %s\n",s);		return(response());	default:		s--;		/* fall into... */	case '\1':	case '\2':		nerrs++;		if (*s != '\n') {			if (!iamremote) {				fflush(stdout);				(void) write(2, s, cp - s);			}			if (lfp != NULL)				(void) fwrite(s, 1, cp - s, lfp);		}		if (resp[0] == '\2')			lostconn(0);		return(-1);	}}/* * Remove temporary files and do any cleanup operations before exiting. */voidcleanup(signo)	int signo;{	(void) unlink(tempfile);	exit(1);}static void#if __STDC__note(const char *fmt, ...)#elsenote(fmt, va_alist)	char *fmt;        va_dcl#endif{	static char buf[BUFSIZ];	va_list ap;#if __STDC__	va_start(ap, fmt);#else	va_start(ap);#endif	(void)vsnprintf(buf, sizeof(buf), fmt, ap);	va_end(ap);	comment(buf);}static voidcomment(s)	char *s;{	char c;	c = '\3';	write(rem, &c, 1);	write(rem, s, strlen(s));	c = '\n';	write(rem, &c, 1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -