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

📄 file.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{char cmd[128];char *argv[5];int fds[2];char *smallenv[] = { "PATH=/bin:/usr/bin:/usr/local/bin", NULL, NULL };   if ((smallenv[1] = getenv("TZ")) != NULL) smallenv[1] -= 3;	/* ouch... */   sprintf(cmd, "%s %s", xcmd, args);   argv[0] = CMD_SH;   argv[1] = "-c";   argv[2] = cmd;   argv[3] = (char *)NULL;   if(pipe(fds) < 0)	return(-1);   if((cmdpid = fork()) < 0) {	close(fds[0]);	close(fds[1]);	return(-1);   }   if(cmdpid == 0) { /* Child */	close(fds[0]);	close(0);	open("/dev/null", O_RDONLY);	dup2(fds[1], 1);	dup2(fds[1], 2);	close(fds[1]);	execve(argv[0], argv, smallenv);	exit(0);   }   close(fds[1]);   return(fds[0]);}/* Same as close if not cmd child started */static int endfdxcmd(fd)int fd;{int s;int cs;   close(fd);   if(cmdpid == -1)	return(0);   s = waitpid(cmdpid, &cs, 0);   cmdpid = -1;   return(0);}/* returns 1 = size could not be determined, *//*         0 = size determined and in filesize */static int asciisize(filename, filesize)char *filename;unsigned long *filesize;{unsigned long count;int fd;char *p, *pp;int cnt;   if((fd = open(filename, O_RDONLY)) < 0) {	printf(msg550, filename, strerror(errno));	return(1);   }   count = 0;   while((cnt = read(fd, buffer, sizeof(buffer))) > 0) {	count += cnt;	p = buffer;	while(cnt > 0)		if((pp = memchr(p, '\n', cnt)) != (char *)NULL) {			count++;			cnt = cnt - 1 - (pp - p);			p = pp + 1;		} else			break;   }   if(cnt == 0) {	*filesize = count;	close(fd);	return(0);   }   printf(msg550, filename, strerror(errno));   close(fd);   return(1);}/* see if we need to run a command to convert the file */static int cnvtfile(name, name2)char *name;char **name2;{struct stat st;static char fname[256];char *p;int mode;   if(!stat(name, &st))			/* file exists can't be a conversion */   	if((st.st_mode & S_IFMT) != S_IFREG) {	/* must be regular file */		printf("550 Not a regular file.\r\n");		return(CNVT_ERROR);	} else		return(CNVT_NONE);   if(errno != ENOENT) {	/* doesn't exist is okay, others are not */	printf(msg550, name, strerror(errno));	return(CNVT_ERROR);   }   /* find out what kind of conversion */   strncpy(fname, name, sizeof(fname));   fname[sizeof(fname)-1] = '\0';   p = fname + strlen(fname);   mode = CNVT_ERROR;   while(p > fname && mode == CNVT_ERROR) {	if(*p == '.') {		if(!strcmp(p, ".tar"))			mode = CNVT_TAR;		else		if(!strcmp(p, ".tar.Z"))			mode = CNVT_TAR_Z;		else		if(!strcmp(p, ".Z"))			mode = CNVT_COMP;		else		if(!strcmp(p, ".tar.gz"))			mode = CNVT_TAR_GZ;		else		if(!strcmp(p, ".gz"))			mode = CNVT_GZIP;		if (mode != CNVT_ERROR) {			/* is there a file to convert? */			*p = '\0';			if (!stat(fname, &st)) break;			*p = '.';			mode = CNVT_ERROR;		}	}	p--;   }   if(mode == CNVT_ERROR) {	printf(msg550, fname, strerror(errno));	return(mode);   }   if(mode == CNVT_COMP || mode == CNVT_GZIP || mode == CNVT_UNCOMP)	if((st.st_mode & S_IFMT) != S_IFREG) {		printf("550 Not a regular file.\r\n");		return(CNVT_ERROR);	}   *name2 = fname;   return(mode);}static int procfile(name)char *name;{int fd;char *name2;static char command[512];   switch(cnvtfile(name, &name2)) {	case CNVT_TAR:		fd = fdxcmd("tar cf -", name2);		break;	case CNVT_TAR_Z:		sprintf(command, "tar cf - %s | compress -q", name2);		fd = fdxcmd(command, "");		break;	case CNVT_COMP:		fd = fdxcmd("compress -cq", name2);		break;	case CNVT_TAR_GZ:		sprintf(command, "tar cf - %s | gzip", name2);		fd = fdxcmd(command, "");		break;	case CNVT_GZIP:		fd = fdxcmd("gzip -c", name2);		break;	case CNVT_UNCOMP:		fd = fdxcmd("compress -dcq", name2);		break;	case CNVT_NONE:		fd = open(name, O_RDONLY);		break;	case CNVT_ERROR:	default:		return(-1);   }   if(fd < 0)	printf(msg550, name, strerror(errno));   return(fd);}/* oh no, they're taking a file */static int sendfile(name, xmode)char *name;int xmode;{char *fname;int fd, s;time_t datastart, dataend;unsigned long datacount;long kbs;char c;char *p;char *op, *ope;off_t sp;int doascii;   if(ChkLoggedIn()) 	return(CleanUpData());   switch(xmode) {	case SEND_NLST:		fname = "NLST";		fd = fdxcmd(CMD_NLST, name);		if(fd < 0)			printf(msg550, name, strerror(errno));		break;	case SEND_LIST:		fname = "LIST";		fd = fdxcmd(CMD_LIST, name);		if(fd < 0)			printf(msg550, name, strerror(errno));		break;	default:		fname = name;		fd = procfile(name);		if(fd < 0)			logit("FAIL", path(fname));		else			logit("SEND", path(fname));   }   if(fd < 0)	return(CleanUpData());   /* set file position at approriate spot */   if(file_restart) {	if(type == TYPE_A) {		sp = 0;		while(sp < file_restart) {			sp++;			s = read(fd, buffer, 1);			if(s < 0) {				printf(msg550, fname, strerror(errno));				endfdxcmd(fd);				file_restart = 0;				return(CleanUpData());			}			if(s == 0) break;			if(*buffer == '\n')				sp++;		}	} else {		sp = lseek(fd, file_restart, SEEK_SET);		if(sp == -1) {			printf(msg550, fname, strerror(errno));			endfdxcmd(fd);			file_restart = 0;			return(CleanUpData());		}	}	if(sp != file_restart) {		printf("550 File restart point error. %lu not %lu\r\n", sp, file_restart);		endfdxcmd(fd);		file_restart = 0;		return(CleanUpData());	}   }   file_restart = 0;   printf("150 File %s okay.  Opening data connection.\r\n", fname);   fflush(stdout);   if(DataConnect()) {	endfdxcmd(fd);	return(GOOD);   }#ifdef DEBUG   fprintf(stderr, "ftpd: parent %d start sendfile \n", getpid());#endif   /* start transfer */   doascii = (type == TYPE_A) ||   	((xmode == SEND_LIST) || (xmode == SEND_NLST)); /* per RFC1123 4.1.2.7 */   datacount = 0;   time(&datastart);   op = bufout; ope = bufout + sizeof(bufout) - 3;   while((s = read(fd, buffer, sizeof(buffer))) > 0) {	datacount += s;	if(doascii) {		p = buffer;		while(s-- > 0) {			c = *p++;			if(c == '\n') {				*op++ = '\r';				datacount++;			}			*op++ = c;			if(op >= ope) {				write(ftpdata_fd, bufout, op - bufout);				op = bufout;			}		}	} else		write(ftpdata_fd, buffer, s);   }   if(op > bufout)	write(ftpdata_fd, bufout, op - bufout);   time(&dataend);#ifdef DEBUG   fprintf(stderr, "ftpd: parent %d end sendfile \n", getpid());#endif   endfdxcmd(fd);   close(ftpdata_fd);   ftpdata_fd = -1;   if(dataend == datastart) dataend++;   kbs = (datacount * 100 / (dataend - datastart)) / 1024;   if(s < 0)	printf("451 Transfer aborted.\r\n");   else	printf("226 Transfer finished successfully. %ld.%02d KB/s\r\n",		(long)(kbs / 100), (int)(kbs % 100));   return(GOOD);}static int recvfile(name, xmode)char *name;int xmode;{char *fname;time_t datastart, dataend;unsigned long datacount;long kbs;char c;char *p;char *op, *ope;int fd, oflag;int s;int gotcr;off_t sp;   if(ChkLoggedIn())	return(CleanUpData());   fname = name;   switch(xmode) {	case RECV_APND:		oflag = O_WRONLY | O_APPEND;		break;	case RECV_UNIQ:		fname = uniqname();		oflag = O_WRONLY | O_CREAT;		break;	default:		oflag = O_WRONLY | O_CREAT | O_TRUNC;   }   if(file_restart)	oflag = O_RDWR;   fd = open(fname, oflag, 0666);   if(fd < 0) {	printf(msg550, fname, strerror(errno));	return(CleanUpData());   }   /* log the received file */   logit("RECV", path(fname));   /* set file position at approriate spot */   if(file_restart) {	if(type == TYPE_A) {		sp = 0;		while(sp < file_restart) {			sp++;			s = read(fd, buffer, 1);			if(s < 0) {				printf(msg550, fname, strerror(errno));				close(fd);				file_restart = 0;				return(CleanUpData());			}			if(s == 0) break;			if(*buffer == '\n')				sp++;		}	} else {		sp = lseek(fd, file_restart, SEEK_SET);		if(sp == -1) {			printf(msg550, fname, strerror(errno));			close(fd);			file_restart = 0;			return(CleanUpData());		}	}	if(sp != file_restart) {		printf("550 File restart point error. %lu not %lu\r\n", sp, file_restart);		close(fd);		file_restart = 0;		return(CleanUpData());	}   }   file_restart = 0;   if(xmode == RECV_UNIQ)   	printf("150 FILE: %s\r\n", fname);	/* per RFC1123 4.1.2.9 */   else	printf("150 File %s okay.  Opening data connection.\r\n", fname);   fflush(stdout);   if(DataConnect()) {   	close(fd);	return(GOOD);   }#ifdef DEBUG   fprintf(stderr, "ftpd: parent %d start recvfile \n", getpid());#endif   /* start receiving file */   datacount = 0;   gotcr = 0;   op = bufout; ope = bufout + sizeof(bufout) - 3;   time(&datastart);   while((s = read(ftpdata_fd, buffer, sizeof(buffer))) > 0) {	datacount += s;	if(type == TYPE_A) {		p = buffer;		while(s-- > 0) {			c = *p++;			if(gotcr) {				gotcr = 0;				if(c != '\n')					*op++ = '\r';			}			if(c == '\r')				gotcr = 1;			else				*op++ = c;			if(op >= ope) {				write(fd, bufout, op - bufout);				op = bufout;			}		}	} else		write(fd, buffer, s);   }   if(gotcr)	*op++ = '\r';   if(op > bufout)	write(fd, bufout, op - bufout);   time(&dataend);#ifdef DEBUG   fprintf(stderr, "ftpd: parent %d end recvfile \n", getpid());#endif   close(fd);   close(ftpdata_fd);    ftpdata_fd = -1;   if(dataend == datastart) dataend++;   kbs = (datacount * 100 / (dataend - datastart)) / 1024;   if(s < 0)	printf("451 Transfer aborted.\r\n");   else {	printf("226 Transfer finished successfully. ");	if(xmode == RECV_UNIQ)		printf("Unique file %s. ", fname);	printf("%ld.%02d KB/s\r\n", (long)(kbs / 100), (int)(kbs % 100));   }   return(GOOD);}static char *uniqname(){static char uniq[14+1];int i;struct stat st;   for(i = 0; i < 1000; i++) {	sprintf(uniq, "ftpd%d%d", getpid(), i);	if(stat(uniq, &st) == -1)		return(uniq);   }   return(uniq);}static char *spath[256];static char *path(fname)char *fname;{char dir[128];   if(getcwd(dir, sizeof(dir)) == (char *)NULL)	sprintf(dir, "???");   if(fname[0] == '/')	sprintf((char *)spath, "%s%s", newroot, fname);   else	if(dir[1] == '\0')		sprintf((char *)spath, "%s%s%s", newroot, dir, fname);	else		sprintf((char *)spath, "%s%s/%s", newroot, dir, fname);   return((char *)spath);}

⌨️ 快捷键说明

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