📄 file.c
字号:
{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 + -