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

📄 synctree.c

📁 minix软件源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					"%s: Master died prematurely.\n", arg0);				exit(1);			}			bp= buf;		}		req= *bp++ & 0xFF;		n--;		if (req >= (int) ENTER) break;		/* Master using slave to print to stdout: */		putchar(req);	}	DPRINTF("%s: request() == %s\n", ORDERS[req - (int) ENTER]);	return (enum orders) req;}static void report(){	int r;	DPRINTF("%s: reporting now!\n", 0);	buckp= bucket;	while (buckn > 0) {		if ((r= write(chan[1], buckp, buckn)) < 0) perrx("report()");		buckp += r;		buckn -= r;	}	buckp= bucket;	buckn= 0;}static void inform(a) enum answers a;/* Slave replies to master. */{	DPRINTF("%s: inform(%s)\n", ANSWERS[(int) a - (int) PATH]);	*buckp++ = (int) a;	buckn++;}#define wwrite(buf, n)	(memcpy(buckp, (buf), (n)), buckp+= (n), buckn+= (n))static void sendnum(n) long n;/* Send number from least to most significant byte. */{#if LITTLE_ENDIAN	wwrite((char *) &n, sizeof(n));#else	char buf[NUMBYTES];	buf[0]= (char) (n >>  0);	buf[1]= (char) (n >>  8);	buf[2]= (char) (n >> 16);	buf[3]= (char) (n >> 24);	wwrite(buf, sizeof(buf));#endif}static void send(buf, n) char *buf; int n;/* Slave sends size and contents of buf. */{	sendnum((long) n);	if (n > 0) wwrite(buf, (size_t) n);}static void sendstat(stp) struct stat *stp;{	sendnum((long) stp->st_mode);	sendnum((long) stp->st_uid);	sendnum((long) stp->st_gid);	sendnum((long) stp->st_rdev);	sendnum((long) stp->st_size);	sendnum((long) stp->st_mtime);}static int ask();static void slave()/* Carry out orders from the master, such as transmitting path names. * Note that the slave uses path, not Spath, the master uses Spath. */{	int f, n;	char buf[CHUNK];	enum { run, done, die } state= run;	do {		switch (request()) {		case ENTER:			enter();			break;		case ADVANCE:			if (!advance() || state == done) {				inform(DONE);				state= done;			} else {				if (linkpath!=nil) {					inform(LINK);					send(linkpath, strlen(linkpath) + 1);				} else				if (S_ISLNK(st.st_mode)) {					inform(SYMLINK);					send(lnkpth, strlen(lnkpth) + 1);				} else {					inform(PATH);				}				send(path, strlen(path) + 1);				sendstat(&st);			}			break;		case CAT:			if ((f= open(path, O_RDONLY))<0) {				fprintf(stderr, "%s: Can't open %s",					arg0, path);				because();				inform(NODATA);				break;			}			inform(DATA);			do {				n= read(f, buf, sizeof(buf));				if (n < 0) perr(path);				send(buf, n);				if (n > 0) report();			} while (n > 0);			close(f);			break;		case CANCEL:			cancellink();			break;		case DIE_BAD:			ex= 1;			/*FALL THROUGH*/		case DIE:			state= die;			break;		case POSITIVE:			inform(ask('y') ? YES : NO);			break;		case NEGATIVE:			inform(ask('n') ? YES : NO);			break;		case PASS_YES:			inform(YES);			break;		case PASS_NO:			inform(NO);			break;		default:			fprintf(stderr, "%s: strange request\n", arg0);			exit(1);		}		report();	} while (state != die);}static int execute(argv) char **argv;/* Execute a command and return its success or failure. */{	int pid, r, status;	if ((pid= fork())<0) {		perr("fork()");		return 0;	}	if (pid == 0) {		execvp(argv[0], argv);		perrx(argv[0]);	}	while ((r= wait(&status)) != pid) {		if (r < 0) {			perr(argv[0]);			return 0;		}	}	return status == 0;}static int removedir(dir) char *dir;/* Remove a directory and its contents. */{	static char *argv[] = { "rm", "-r", nil, nil };	printf("(rm -r %s)\n", dir);	argv[2]= dir;	return execute(argv);}static void order(o) enum orders o;/* Master tells slave what to do. */{	char c= (char) o;	DPRINTF("%s: order(%s)\n", ORDERS[o - (int) ENTER]);	if (write(chan[1], &c, 1) != 1) perrx("order()");}static void rread(buf, n) char *buf; int n;/* Master gets buf of size n from slave, doing multiple reads if needed. */{	int r;	while (n > 0) {		if (buckn == 0) {			switch (buckn= read(chan[0], bucket, BUCKSIZE)) {			case -1:				perrx("reply channel from slave");			case  0:				fprintf(stderr,					"%s: slave died prematurely.\n",					arg0);				exit(1);			}			buckp= bucket;		}		r= n < buckn ? n : buckn;		memcpy(buf, buckp, r);		buckp+= r;		buckn-= r;		buf+= r;		n-= r;	}}static enum answers answer()/* Master reads slave's reply. */{	char c;	int a;	rread(&c, 1);	a= c & 0xFF;	DPRINTF("%s: answer() == %s\n", ANSWERS[a - (int) PATH]);	return (enum answers) a;}static long recnum()/* Read number as pack of bytes from least to most significant.  The data * is on the wire in little-endian format.  (Mostly run on PC's). */{#if LITTLE_ENDIAN	long n;	rread((char *) &n, (int) sizeof(n));	return n;#else	unsigned char buf[NUMBYTES];	rread(buf, sizeof(buf));	return	buf[0]		| ((unsigned) buf[1] << 8)		| ((unsigned long) buf[2] << 16)		| ((unsigned long) buf[3] << 24);#endif}static int receive(buf, max) char *buf; int max;/* Master get's data from slave, by first reading size, then data. */{	int n;	n= recnum();	if (n > max) {		fprintf(stderr, "%s: panic: Can't read %d bytes\n", arg0, n);		exit(1);	}	if (n > 0) rread(buf, n);	return n;}static void recstat(stp) struct stat *stp;{	stp->st_mode= recnum();	stp->st_uid= recnum();	stp->st_gid= recnum();	stp->st_rdev= recnum();	stp->st_size= recnum();	stp->st_mtime= recnum();}static int key(){	int c;	static int tty= -1;	if (tty < 0) tty= isatty(0);	if (feof(stdin) || (c= getchar()) == EOF) {		c= '\n';		if (tty) putchar('\n');	}	if (!tty) putchar(c);	return c;}static int ask(def) int def;/* Ask for a yes or no, anything else means choose def. */{	int y, c;	if (chan[0] == 0) {		/* I'm running remote, tell the slave to ask. */		fflush(stdout);		order(def == 'y' ? POSITIVE : NEGATIVE);		return answer() == YES;	}	printf("? (%c) ", def);	fflush(stdout);	do c= key(); while (c == ' ' || c == '\t');	y= c;	while (c != '\n') c= key();	if (y != 'y' && y != 'Y' && y != 'n' && y != 'N') y= def;	return y == 'y' || y == 'Y';}static void setmodes(silent) int silent;{	struct stat st;	int change= 0;	struct utimbuf tms;	errno= 0;	getstat(Spath, &st);	if (backup && silent) {		setstat(st.st_ino, &Sst);		getstat(Spath, &st);	}	if (S_ISLNK(st.st_mode)) return;	if (errno == 0 && st.st_mode != Sst.st_mode) {		if (!backup) chmod(Spath, Sst.st_mode & 07777);		change= 1;	}	if (errno == 0		&& (st.st_uid != Sst.st_uid || st.st_gid != Sst.st_gid)		&& (backup || geteuid() == 0)	) {		errno= 0;		if (!backup) chown(Spath, Sst.st_uid, Sst.st_gid);		change= 1;	}	if (backup && !silent) setstat(st.st_ino, &Sst);	if (errno == 0 && S_ISREG(Sst.st_mode) && st.st_mtime != Sst.st_mtime) {		time(&tms.actime);		tms.modtime= Sst.st_mtime;		errno= 0;		utime(Spath, &tms);		change= 1;	}	if (errno != 0) {		fprintf(stderr, "%s: Can't set modes of %s", arg0, Spath);		because();	} else	if (change && !silent) {		printf("Mode changed of %s\n", Spath);	}}static void makeold(){	static struct utimbuf tms= { 0, 0 };	if (utime(Spath, &tms) < 0) {		if (errno != ENOENT) {			fprintf(stderr,				"%s: can't make %s look old", arg0, Spath);			because();		}	} else {		fprintf(stderr, "%s: made %s look old.\n", arg0, Spath);	}}static int busy= 0;static void bail_out(sig) int sig;{	signal(sig, SIG_IGN);	fprintf(stderr, "%s: Exiting after signal %d\n", arg0, sig);	if (busy) {		fprintf(stderr, "%s: was installing %s\n", arg0, Spath);		makeold();	}	order(DIE_BAD);	exit(sig);}static int makenode(name, mode, addr, size)	char *name; int mode; dev_t addr; off_t size;{	int r;	if (!backup) {		r= mknod(name, mode, addr);	} else {		if ((r= creat(name, 0644)) >= 0) close(r);	}	return r;}static void add(update) int update;/* Add Spath to the filesystem. */{	int f, n;	char buf[CHUNK];	int forced_update= force && update;	if (Slinkpath != nil && !S_ISLNK(Sst.st_mode)) {		if (interact && !update) {			printf("Link %s to %s", Spath, Slinkpath);			if (!ask('n')) return;		}		if (link(Slinkpath, Spath) >= 0) {			printf("Linked %s to %s\n", Spath, Slinkpath);			return;		} else {			fprintf(stderr,				"%s: Can't link %s to %s",				arg0, Slinkpath, Spath);			because();			/* Try to install instead. */		}	}	switch (Sst.st_mode & S_IFMT) {	case S_IFDIR:		if (!force) {			printf("Add dir %s", Spath);			if (!ask('n')) return;		}		if (mkdir(Spath, backup ? 0755 : Sst.st_mode) < 0) {			perr(Spath);			return;		}		printf("Directory %s created.\n", Spath);		order(ENTER);		break;	case S_IFBLK:	case S_IFCHR:	case S_IFIFO:		if (interact && !update) {			printf("Create special file %s", Spath);			if (!ask('n')) { order(CANCEL); return; }		}		if (makenode(Spath, Sst.st_mode, Sst.st_rdev, Sst.st_size)<0) {			fprintf(stderr,				"%s: Can't create special file %s",

⌨️ 快捷键说明

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