static void openwithcontrol (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl)); unsigned int i; ctrl->iotag = lua_newtag(L); ctrl->closedtag = lua_newtag(L); for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { /* put `ctrl' as upvalue for these functions */ lua_pushvalue(L, -1); lua_pushcclosure(L, iolibtag[i].func, 1); lua_setglobal(L, iolibtag[i].name); } /* create references to variable names */ lua_pushstring(L, filenames[INFILE]); ctrl->ref[INFILE] = lua_ref(L, 1); lua_pushstring(L, filenames[OUTFILE]); ctrl->ref[OUTFILE] = lua_ref(L, 1); /* predefined file handles */ setfile(L, ctrl, stdin, INFILE); setfile(L, ctrl, stdout, OUTFILE); setfilebyname(L, ctrl, stdin, "_STDIN"); setfilebyname(L, ctrl, stdout, "_STDOUT"); setfilebyname(L, ctrl, stderr, "_STDERR"); /* close files when collected */ lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */ lua_settagmethod(L, ctrl->iotag, "gc"); }
static void openwithtags() { int32 iotag = lua_newtag(); int32 closedtag = lua_newtag(); uint32 i; for (i = 0; i < sizeof(iolibtag) / sizeof(iolibtag[0]); i++) { // put both tags as upvalues for these functions lua_pushnumber(iotag); lua_pushnumber(closedtag); lua_pushCclosure(iolibtag[i].func, 2); lua_setglobal(iolibtag[i].name); } g_fin = new LuaFile(); g_fin->_stdin = true; setfile(addfile(g_fin), FINPUT, iotag); g_fout = new LuaFile(); g_fout->_stdout = true; setfile(addfile(g_fout), FOUTPUT, iotag); g_stdin = new LuaFile(); g_stdin->_stdin = true; setfile(addfile(g_stdin), "_STDIN", iotag); g_stdout = new LuaFile(); g_stdout->_stdout = true; setfile(addfile(g_stdout), "_STDOUT", iotag); g_stderr = new LuaFile(); g_stderr->_stderr = true; setfile(addfile(g_stderr), "_STDERR", iotag); }
/** * copy a directory between branches (includes all contents of the directory) */ int copy_directory(const char *path, int branch_ro, int branch_rw) { DBG("%s\n", path); /* create the directory on the destination branch */ int res = path_create(path, branch_ro, branch_rw); if (res != 0) { RETURN(res); } /* determine path to source directory on read-only branch */ char from[PATHLEN_MAX]; if (BUILD_PATH(from, uopt.branches[branch_ro].path, path)) RETURN(1); DIR *dp = opendir(from); if (dp == NULL) RETURN(1); struct dirent *de; while ((de = readdir(dp)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; char member[PATHLEN_MAX]; if (BUILD_PATH(member, path, "/", de->d_name)) { res = 1; break; } res = cow_cp(member, branch_ro, branch_rw, true); if (res != 0) break; } closedir(dp); struct stat buf; lstat(from, &buf); setfile(from, &buf); RETURN(res); }
/****************************************************************************** * Prim_PCLOSE - close a pipe opened by Prim_POPEN(). * (code stolen from xlfio.c:xclose()) * * syntax: (pclose <stream>) * <stream> is a stream created by popen. * returns T if the command executed successfully, otherwise, * returns the exit status of the opened command. * * Added to XLISP by Niels Mayer ******************************************************************************/ LVAL Prim_PCLOSE() { extern LVAL true; LVAL fptr; int result; /* get file pointer */ fptr = xlgastream(); xllastarg(); /* make sure the file exists */ if (getfile(fptr) == NULL) xlfail("file not open"); /* close the pipe */ result = pclose(getfile(fptr)); if (result == -1) xlfail("<stream> has not been opened with popen"); setfile(fptr,NULL); /* return T if success (exit status 0), else return exit status */ return (result ? cvfixnum(result) : true); }
int null_close(void *cookie, struct z_info *info, const char *name, struct stat *sb) { null_stream *s = (null_stream*) cookie; int err = 0; if (s == NULL) return -1; if (info != NULL) { info->mtime = 0; info->crc = (u_int32_t)-1; info->hlen = 0; info->total_in = (off_t) s->total_in; info->total_out = (off_t) s->total_out; } setfile(name, s->fd, sb); err = close(s->fd); free(s); return err; }
int copy_link(const FTSENT *p, int exists) { int len; char llink[PATH_MAX]; if (exists && nflag) { if (vflag) printf("%s not overwritten\n", to.p_path); return (1); } if ((len = readlink(p->fts_path, llink, sizeof(llink) - 1)) == -1) { warn("readlink: %s", p->fts_path); return (1); } llink[len] = '\0'; if (exists && unlink(to.p_path)) { warn("unlink: %s", to.p_path); return (1); } if (symlink(llink, to.p_path)) { warn("symlink: %s", llink); return (1); } return (pflag ? setfile(p->fts_statp, -1) : 0); }
void outputfile(char *buf, char *orgbuf, char *ext) { if (has_output_file) AddExt(buf, ext); else setfile(buf, orgbuf, ext); }
/** * copy a special file, actually we recreate this file and only copy * its stat() data */ int copy_special(struct cow *cow) { if (mknod(cow->to_path, cow->stat->st_mode, cow->stat->st_rdev)) { syslog(LOG_WARNING, "mknod: %s", cow->to_path); return (1); } return setfile(cow->to_path, cow->stat); }
/** * copy a fifo, actually we recreate the fifo and only copy * its stat() data **/ int copy_fifo(struct cow *cow) { if (mkfifo(cow->to_path, cow->stat->st_mode)) { syslog(LOG_WARNING, "mkfifo: %s", cow->to_path); return (1); } return setfile(cow->to_path, cow->stat); }
/* cvfile - convert a file pointer to a stream */ LVAL cvfile(FILE *fp) { LVAL val; val = newnode(STREAM); setfile(val,fp); setsavech(val,'\0'); return (val); }
/* cvfile - convert a file pointer to a file */ NODE *cvfile( FILE *fp) { NODE *val; val = newnode(FPTR); setfile(val,fp); setsavech(val,0); return (val); }
static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { if (f == NULL) return pushresult(L, 0); else { setfile(L, ctrl, f, inout); lua_pushusertag(L, f, ctrl->iotag); return 1; } }
static void openwithtags (void) { int iotag = lua_newtag(); int closedtag = lua_newtag(); int i; for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { /* put both tags as upvalues for these functions */ lua_pushnumber(iotag); lua_pushnumber(closedtag); lua_pushCclosure(iolibtag[i].func, 2); lua_setglobal(iolibtag[i].name); } setfile(stdin, FINPUT, iotag); setfile(stdout, FOUTPUT, iotag); setfile(stdin, "_STDIN", iotag); setfile(stdout, "_STDOUT", iotag); setfile(stderr, "_STDERR", iotag); }
/* * Change to another file. With no argument, print information about * the current file. */ int file(char **argv) { if (argv[0] == NULL) { newfileinfo(0); return (0); } if (setfile(*argv) < 0) return (1); announce(); return (0); }
/** * * Sets a file/dir stat to it's original in the RO branch * path: relative path to the file/dir * nbranch_ro: number of the branch used as ro * nbranch_rw: number of the branch used as rw */ int copy_ro_rw_stat(char * path, int nbranch_ro, int nbranch_rw) { if (nbranch_ro == nbranch_rw) RETURN(0); // same file -> nothing to do here char ro_dir_path[PATHLEN_MAX]; // original dir path char rw_dir_path[PATHLEN_MAX]; // dir path to create sprintf(ro_dir_path, "%s%s", uopt.branches[nbranch_ro].path, path); struct stat buf; if (stat(ro_dir_path, &buf) == -1) RETURN(1); sprintf(rw_dir_path, "%s%s", uopt.branches[nbranch_rw].path, path); if (setfile(rw_dir_path, &buf)) RETURN(1); // directory already removed by another process? RETURN(0); }
int copy_fifo(struct stat *from_stat, int exists) { if (exists && unlink(to.p_path)) { warn("unlink: %s", to.p_path); return (1); } if (mkfifo(to.p_path, from_stat->st_mode)) { warn("mkfifo: %s", to.p_path); return (1); } return (pflag ? setfile(from_stat, -1) : 0); }
int copy_special(struct stat *from_stat, int exists) { if (exists && unlink(to.p_path)) { warn("unlink: %s", to.p_path); return (1); } if (mknod(to.p_path, from_stat->st_mode, from_stat->st_rdev)) { warn("mknod: %s", to.p_path); return (1); } return (pflag ? setfile(from_stat, -1) : 0); }
void setreffile(struct file *datafile,struct data *d,char *refpar) { char filename[MAXPATHLEN],refname[MAXPATHLEN]; int i,filenamectr=0,refnamectr=0; /* Get the reference name from the reference parameter */ strcpy(refname,*sval(refpar,&d->p)); /* If recon is straight after acquisition ... */ if (vnmrj_recon && spar(d,"file","exp")) { /* Use the reference name as is */ setfile(datafile,refname); } else { if (vnmrj_recon) { /* Recon from within VnmrJ */ /* Use the path as defined in the parameter "file" */ strcpy(filename,*sval("file",&d->p)); } else { /* Recon outside of VnmrJ */ /* Use the path as defined in d->file */ strcpy(filename,d->file); filename[strlen(filename)-8]=0; /* NULL terminate to remove .fid/fid */ } /* Now use the path as defined in filename */ for (i=0;i<strlen(filename);i++) if (filename[i] == '/') filenamectr=i; if (filenamectr>0) filenamectr++; for (i=0;i<strlen(refname);i++) if (refname[i] == '/') refnamectr=i; if (refnamectr>0) refnamectr++; for (i=refnamectr;i<strlen(refname);i++) { filename[filenamectr]=refname[i]; filenamectr++; } filename[filenamectr]=0; /* NULL terminate */ setfile(datafile,filename); } }
int eqn(int argc,char **argv) { int i, type; setfile(argc,argv); init_tbl(); /* install keywords in tables */ while ((type=getline(&in, &insize)) != EOF) { eqline = linect; if (type == lefteq) do_inline(); else if (*in == '.') { char *p; printf("%s",in); for (p = in + 1; *p == ' ' || *p == '\t'; p++); if (!*p || *p != 'E' || p[1] != 'Q') continue; for (i=11; i<100; used[i++]=0); printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); printf(".if \\n(.X .nrf 99 \\n(.s\n"); markline = 0; init(); yyparse(); if (eqnreg>0) { printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg); /* printf(".if \\n(%d>\\n(.l .tm too-long eqn, file %s, between lines %d-%d\n", */ /* eqnreg, svargv[ifile], eqline, linect); */ printf(".nr MK %d\n", markline); /* for -ms macros */ printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht); printf(".rn %d 10\n", eqnreg); if(!noeqn)printf("\\*(10\n"); } printf(".ps \\n(99\n.ft \\n(98\n"); printf(".EN"); if (lastchar == EOF) { putchar('\n'); break; } if (putchar(lastchar) != '\n') while (putchar(gtc()) != '\n'); } else printf("%s",in); } return(0); }
/* xclose - close a file */ LVAL xclose(void) { LVAL fptr; /* get file pointer */ fptr = xlgastream(); xllastarg(); /* make sure the file exists */ if (getfile(fptr) == NULL) xlfail("file not open"); /* close the file */ osclose(getfile(fptr)); setfile(fptr,NULL); /* return nil */ return (NIL); }
int copy_link(FTSENT *p, int exists) { int len; char target[MAXPATHLEN]; if ((len = readlink(p->fts_path, target, sizeof(target)-1)) == -1) { warn("readlink: %s", p->fts_path); return (1); } target[len] = '\0'; if (exists && unlink(to.p_path)) { warn("unlink: %s", to.p_path); return (1); } if (symlink(target, to.p_path)) { warn("symlink: %s", target); return (1); } return (pflag ? setfile(p->fts_statp, 0) : 0); }
int copy_link(FTSENT *p, int exists) { int len; char name[PATH_MAX]; if ((len = readlink(p->fts_path, name, sizeof(name)-1)) == -1) { warn("readlink: %s", p->fts_path); return (1); } name[len] = '\0'; if (exists && unlink(to.p_path)) { warn("unlink: %s", to.p_path); return (1); } if (symlink(name, to.p_path)) { warn("symlink: %s", name); return (1); } return (pflag ? setfile(p->fts_statp, -1) : 0); }
static int ar_getdata(Pax_t* pax, register Archive_t* ap, register File_t* f, int wfd) { register Ar_t* ar = (Ar_t*)ap->data; if (ar->ent->offset < 0) { error(3, "%s: read not supported for %s format", f->name, ap->format->name); return -1; } if (wfd >= 0) { if (ardircopy(ar->dir, ar->ent, wfd) < 0) { error(ERROR_SYSTEM|2, "%s: copy error", f->name); return -1; } closeout(ap, f, wfd); setfile(ap, f); } return 1; }
static int ftw_copy_link(const struct FTW *p, const char *spath, const struct stat *sstp, int exists) { int len; char llink[PATH_MAX]; if ((len = readlink(spath, llink, sizeof(llink) - 1)) == -1) { SLOG("readlink: %s: %s", spath, strerror(errno)); return (1); } llink[len] = '\0'; if (exists && unlink(to.p_path)) { SLOG("unlink: %s: %s", to.p_path, strerror(errno)); return (1); } if (symlink(llink, to.p_path)) { SLOG("symlink: %s: %s", llink, strerror(errno)); return (1); } return (pflag ? setfile(sstp, -1) : 0); }
/** * Actually create the directory here. */ static int do_create(const char *path, int nbranch_ro, int nbranch_rw) { DBG_IN(); char dirp[PATHLEN_MAX]; // dir path to create sprintf(dirp, "%s%s", uopt.branches[nbranch_rw].path, path); struct stat buf; int res = stat(dirp, &buf); if (res != -1) return 0; // already exists if (nbranch_ro == nbranch_rw) { // special case nbranch_ro = nbranch_rw, this is if we a create // unionfs meta directories, so not directly on cow operations buf.st_mode = S_IRWXU | S_IRWXG; } else { // data from the ro-branch char o_dirp[PATHLEN_MAX]; // the pathname we want to copy sprintf(o_dirp, "%s%s", uopt.branches[nbranch_ro].path, path); res = stat(o_dirp, &buf); if (res == -1) return 1; // lower level branch removed in the mean time? } res = mkdir(dirp, buf.st_mode); if (res == -1) { usyslog(LOG_DAEMON, "Creating %s failed: \n", dirp); return 1; } if (nbranch_ro == nbranch_rw) return 0; // the special case again if (setfile(dirp, &buf)) return 1; // directory already removed by another process? // TODO: time, but its values are modified by the next dir/file creation steps? return 0; }
int copy_file(const FTSENT *entp, int dne) { static char buf[MAXBSIZE]; struct stat *fs; ssize_t wcount, rcount; size_t wresid; off_t wtotal; int ch, checkch, from_fd = 0, rval, to_fd = 0; char *bufp; #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED char *p; #endif if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) { warn("%s", entp->fts_path); return (1); } fs = entp->fts_statp; /* * If the file exists and we're interactive, verify with the user. * If the file DNE, set the mode to be the from file, minus setuid * bits, modified by the umask; arguably wrong, but it makes copying * executables work right and it's been that way forever. (The * other choice is 666 or'ed with the execute bits on the from file * modified by the umask.) */ if (!dne) { #define YESNO "(y/n [n]) " if (nflag) { if (vflag) printf("%s not overwritten\n", to.p_path); close(from_fd); return (0); } else if (iflag) { fprintf(stderr, "overwrite %s? %s", to.p_path, YESNO); checkch = ch = getchar(); while (ch != '\n' && ch != EOF) ch = getchar(); if (checkch != 'y' && checkch != 'Y') { close(from_fd); fprintf(stderr, "not overwritten\n"); return (1); } } if (fflag) { /* remove existing destination file name, * create a new file */ unlink(to.p_path); if (!lflag) to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, fs->st_mode & ~(S_ISUID | S_ISGID)); } else { if (!lflag) /* overwrite existing destination file name */ to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0); } } else { if (!lflag) to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, fs->st_mode & ~(S_ISUID | S_ISGID)); } if (to_fd == -1) { warn("%s", to.p_path); close(from_fd); return (1); } rval = 0; if (!lflag) { /* * Mmap and write if less than 8M (the limit is so we don't totally * trash memory on big files. This is really a minor hack, but it * wins some CPU back. * Some filesystems, such as smbnetfs, don't support mmap, * so this is a best-effort attempt. */ #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED if (S_ISREG(fs->st_mode) && fs->st_size > 0 && fs->st_size <= 8 * 1024 * 1024 && (p = mmap(NULL, (size_t)fs->st_size, PROT_READ, MAP_SHARED, from_fd, (off_t)0)) != MAP_FAILED) { wtotal = 0; for (bufp = p, wresid = fs->st_size; ; bufp += wcount, wresid -= (size_t)wcount) { wcount = write(to_fd, bufp, wresid); if (wcount <= 0) break; wtotal += wcount; if (info) { info = 0; fprintf(stderr, "%s -> %s %3d%%\n", entp->fts_path, to.p_path, cp_pct(wtotal, fs->st_size)); } if (wcount >= (ssize_t)wresid) break; } if (wcount != (ssize_t)wresid) { warn("%s", to.p_path); rval = 1; } /* Some systems don't unmap on close(2). */ if (munmap(p, fs->st_size) < 0) { warn("%s", entp->fts_path); rval = 1; } } else #endif { wtotal = 0; while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) { for (bufp = buf, wresid = rcount; ; bufp += wcount, wresid -= wcount) { wcount = write(to_fd, bufp, wresid); if (wcount <= 0) break; wtotal += wcount; if (info) { info = 0; fprintf(stderr, "%s -> %s %3d%%\n", entp->fts_path, to.p_path, cp_pct(wtotal, fs->st_size)); } if (wcount >= (ssize_t)wresid) break; } if (wcount != (ssize_t)wresid) { warn("%s", to.p_path); rval = 1; break; } } if (rcount < 0) { warn("%s", entp->fts_path); rval = 1; } } } else { if (link(entp->fts_path, to.p_path)) { warn("%s", to.p_path); rval = 1; } } /* * Don't remove the target even after an error. The target might * not be a regular file, or its attributes might be important, * or its contents might be irreplaceable. It would only be safe * to remove it if we created it and its length is 0. */ if (!lflag) { if (pflag && setfile(fs, to_fd)) rval = 1; if (close(to_fd)) { warn("%s", to.p_path); rval = 1; } } close(from_fd); return (rval); }
PUBLIC int main(int argc, char *argv[]) { jmp_buf jmpbuf; struct sigaction sa; struct name *to, *cc, *bcc, *smopts; #ifdef MIME_SUPPORT struct name *attach_optargs; struct name *attach_end; #endif char *subject; const char *ef; char nosrc = 0; const char *rc; int Hflag; int i; /* * For portability, call setprogname() early, before * getprogname() is called. */ (void)setprogname(argv[0]); /* * Set up a reasonable environment. * Figure out whether we are being run interactively, * start the SIGCHLD catcher, and so forth. * (Other signals are setup later by sig_setup().) */ (void)sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa.sa_handler = sigchild; (void)sigaction(SIGCHLD, &sa, NULL); if (isatty(0)) assign(ENAME_INTERACTIVE, ""); image = -1; /* * Now, determine how we are being used. * We successively pick off - flags. * If there is anything left, it is the base of the list * of users to mail to. Argp will be set to point to the * first of these users. */ rc = NULL; ef = NULL; to = NULL; cc = NULL; bcc = NULL; smopts = NULL; subject = NULL; Hflag = 0; #ifdef MIME_SUPPORT attach_optargs = NULL; attach_end = NULL; while ((i = getopt(argc, argv, ":~EH:INT:a:b:c:dfinr:s:u:v")) != -1) #else while ((i = getopt(argc, argv, ":~EH:INT:b:c:dfinr:s:u:v")) != -1) #endif { switch (i) { case 'T': /* * Next argument is temp file to write which * articles have been read/deleted for netnews. */ Tflag = optarg; if ((i = creat(Tflag, 0600)) < 0) { warn("%s", Tflag); exit(1); } (void)close(i); break; #ifdef MIME_SUPPORT case 'a': { struct name *np; np = nalloc(optarg, 0); if (attach_end == NULL) attach_optargs = np; else { np->n_blink = attach_end; attach_end->n_flink = np; } attach_end = np; break; } #endif case 'u': /* * Next argument is person to pretend to be. */ myname = optarg; (void)unsetenv("MAIL"); break; case 'i': /* * User wants to ignore interrupts. * Set the variable "ignore" */ assign(ENAME_IGNORE, ""); break; case 'd': debug++; break; case 'r': rc = optarg; break; case 's': /* * Give a subject field for sending from * non terminal */ subject = optarg; break; case 'f': /* * User is specifying file to "edit" with Mail, * as opposed to reading system mailbox. * If no argument is given after -f, we read his * mbox file. * * getopt() can't handle optional arguments, so here * is an ugly hack to get around it. */ if ((argv[optind]) && (argv[optind][0] != '-')) ef = argv[optind++]; else ef = "&"; break; case 'H': /* * Print out the headers and quit. */ Hflag = get_Hflag(argv); break; case 'n': /* * User doesn't want to source /usr/lib/Mail.rc */ nosrc++; break; case 'N': /* * Avoid initial header printing. */ assign(ENAME_NOHEADER, ""); break; case 'v': /* * Send mailer verbose flag */ assign(ENAME_VERBOSE, ""); break; case 'I': case '~': /* * We're interactive */ assign(ENAME_INTERACTIVE, ""); break; case 'c': /* * Get Carbon Copy Recipient list */ cc = cat(cc, lexpand(optarg, GCC)); break; case 'b': /* * Get Blind Carbon Copy Recipient list */ bcc = cat(bcc, lexpand(optarg, GBCC)); break; case 'E': /* * Don't send empty files. */ assign(ENAME_DONTSENDEMPTY, ""); break; case ':': /* * An optarg was expected but not found. */ if (optopt == 'H') { Hflag = get_Hflag(NULL); break; } (void)fprintf(stderr, "%s: option requires an argument -- %c\n", getprogname(), optopt); /* FALLTHROUGH */ case '?': /* * An unknown option flag. We need to do the * error message. */ if (optopt != '?') (void)fprintf(stderr, "%s: unknown option -- %c\n", getprogname(), optopt); usage(); /* print usage message and die */ /*NOTREACHED*/ } } for (i = optind; (argv[i]) && (*argv[i] != '-'); i++) to = cat(to, nalloc(argv[i], GTO)); for (/*EMPTY*/; argv[i]; i++) smopts = cat(smopts, nalloc(argv[i], GSMOPTS)); /* * Check for inconsistent arguments. */ if (to == NULL && (subject != NULL || cc != NULL || bcc != NULL)) errx(EXIT_FAILURE, "You must specify direct recipients with -s, -c, or -b."); if (ef != NULL && to != NULL) { errx(EXIT_FAILURE, "Cannot give -f and people to send to."); } if (Hflag != 0 && to != NULL) errx(EXIT_FAILURE, "Cannot give -H and people to send to."); #ifdef MIME_SUPPORT if (attach_optargs != NULL && to == NULL) errx(EXIT_FAILURE, "Cannot give -a without people to send to."); #endif tinit(); /* must be done before loading the rcfile */ input = stdin; mailmode = Hflag ? mm_hdrsonly : to ? mm_sending : mm_receiving; spreserve(); if (!nosrc) load(_PATH_MASTER_RC); /* * Expand returns a savestr, but load only uses the file name * for fopen, so it's safe to do this. */ if (rc == NULL && (rc = getenv("MAILRC")) == NULL) rc = "~/.mailrc"; load(expand(rc)); setscreensize(); /* do this after loading the rcfile */ #ifdef USE_EDITLINE /* * This is after loading the MAILRC so we can use value(). * Avoid editline in mm_hdrsonly mode or pipelines will screw * up. XXX - there must be a better way! */ if (mailmode != mm_hdrsonly) init_editline(); #endif sig_setup(); switch (mailmode) { case mm_sending: (void)mail(to, cc, bcc, smopts, subject, mime_attach_optargs(attach_optargs)); /* * why wait? */ exit(senderr); break; /* XXX - keep lint happy */ case mm_receiving: case mm_hdrsonly: /* * Ok, we are reading mail. * Decide whether we are editing a mailbox or reading * the system mailbox, and open up the right stuff. */ if (ef == NULL) ef = "%"; if (setfile(ef) < 0) exit(1); /* error already reported */ if (value(ENAME_QUIET) == NULL) (void)printf("Mail version %s. Type ? for help.\n", version); if (mailmode == mm_hdrsonly) show_headers_and_exit(Hflag); /* NORETURN */ announce(); (void)fflush(stdout); if (setjmp(jmpbuf) != 0) { /* Return here if quit() fails below. */ (void)printf("Use 'exit' to quit without saving changes.\n"); } commands(); /* Ignore these signals from now on! */ (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); quit(jmpbuf); break; default: assert(/*CONSTCOND*/0); break; } return 0; }
static void decompress(const char *in, const char *out, int bits) { size_t nr; struct stat sb; FILE *ifp, *ofp; int exists, isreg, oreg; u_char buf[1024]; exists = !stat(out, &sb); if (!force && exists && S_ISREG(sb.st_mode) && !permission(out)) return; isreg = oreg = !exists || S_ISREG(sb.st_mode); ifp = ofp = NULL; if ((ifp = zopen(in, "r", bits)) == NULL) { cwarn("%s", in); return; } if (stat(in, &sb)) { cwarn("%s", in); goto err; } if (!S_ISREG(sb.st_mode)) isreg = 0; /* * Try to read the first few uncompressed bytes from the input file * before blindly truncating the output file. */ if ((nr = fread(buf, 1, sizeof(buf), ifp)) == 0) { cwarn("%s", in); (void)fclose(ifp); return; } if ((ofp = fopen(out, "w")) == NULL || (nr != 0 && fwrite(buf, 1, nr, ofp) != nr)) { cwarn("%s", out); (void)fclose(ifp); return; } while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0) if (fwrite(buf, 1, nr, ofp) != nr) { cwarn("%s", out); goto err; } if (ferror(ifp) || fclose(ifp)) { cwarn("%s", in); goto err; } ifp = NULL; if (fclose(ofp)) { cwarn("%s", out); goto err; } if (isreg) { setfile(out, &sb); if (unlink(in)) cwarn("%s", in); } return; err: if (ofp) { if (oreg) (void)unlink(out); (void)fclose(ofp); } if (ifp) (void)fclose(ifp); }
static void compress(const char *in, const char *out, int bits) { size_t nr; struct stat isb, sb; FILE *ifp, *ofp; int exists, isreg, oreg; u_char buf[1024]; exists = !stat(out, &sb); if (!force && exists && S_ISREG(sb.st_mode) && !permission(out)) return; isreg = oreg = !exists || S_ISREG(sb.st_mode); ifp = ofp = NULL; if ((ifp = fopen(in, "r")) == NULL) { cwarn("%s", in); return; } if (stat(in, &isb)) { /* DON'T FSTAT! */ cwarn("%s", in); goto err; } if (!S_ISREG(isb.st_mode)) isreg = 0; if ((ofp = zopen(out, "w", bits)) == NULL) { cwarn("%s", out); goto err; } while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0) if (fwrite(buf, 1, nr, ofp) != nr) { cwarn("%s", out); goto err; } if (ferror(ifp) || fclose(ifp)) { cwarn("%s", in); goto err; } ifp = NULL; if (fclose(ofp)) { cwarn("%s", out); goto err; } ofp = NULL; if (isreg) { if (stat(out, &sb)) { cwarn("%s", out); goto err; } if (!force && sb.st_size >= isb.st_size) { if (verbose) (void)fprintf(stderr, "%s: file would grow; left unmodified\n", in); eval = 2; if (unlink(out)) cwarn("%s", out); goto err; } setfile(out, &isb); if (unlink(in)) cwarn("%s", in); if (verbose) { (void)fprintf(stderr, "%s: ", out); if (isb.st_size > sb.st_size) (void)fprintf(stderr, "%.0f%% compression\n", ((float)sb.st_size / isb.st_size) * 100.0); else (void)fprintf(stderr, "%.0f%% expansion\n", ((float)isb.st_size / sb.st_size) * 100.0); } } return; err: if (ofp) { if (oreg) (void)unlink(out); (void)fclose(ofp); } if (ifp) (void)fclose(ifp); }
int copy_file(FTSENT *entp, int dne) { static char *buf; static char *zeroes; struct stat to_stat, *fs; int ch, checkch, from_fd, rcount, rval, to_fd, wcount; #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED char *p; #endif if (!buf) { buf = malloc(MAXBSIZE); if (!buf) err(1, "malloc"); } if (!zeroes) { zeroes = malloc(MAXBSIZE); if (!zeroes) err(1, "malloc"); memset(zeroes, 0, MAXBSIZE); } if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) { warn("%s", entp->fts_path); return (1); } fs = entp->fts_statp; /* * In -f (force) mode, we always unlink the destination first * if it exists. Note that -i and -f are mutually exclusive. */ if (!dne && fflag) (void)unlink(to.p_path); /* * If the file exists and we're interactive, verify with the user. * If the file DNE, set the mode to be the from file, minus setuid * bits, modified by the umask; arguably wrong, but it makes copying * executables work right and it's been that way forever. (The * other choice is 666 or'ed with the execute bits on the from file * modified by the umask.) */ if (!dne && !fflag) { if (iflag) { (void)fprintf(stderr, "overwrite %s? ", to.p_path); checkch = ch = getchar(); while (ch != '\n' && ch != EOF) ch = getchar(); if (checkch != 'y' && checkch != 'Y') { (void)close(from_fd); return (0); } } to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0); } else to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT, fs->st_mode & ~(S_ISTXT | S_ISUID | S_ISGID)); if (to_fd == -1) { warn("%s", to.p_path); (void)close(from_fd); return (1); } rval = 0; /* * Mmap and write if less than 8M (the limit is so we don't totally * trash memory on big files. This is really a minor hack, but it * wins some CPU back. */ #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED /* XXX broken for 0-size mmap */ if (fs->st_size <= 8 * 1048576) { if ((p = mmap(NULL, (size_t)fs->st_size, PROT_READ, MAP_FILE|MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) { warn("mmap: %s", entp->fts_path); rval = 1; } else { madvise(p, fs->st_size, MADV_SEQUENTIAL); if (write(to_fd, p, fs->st_size) != fs->st_size) { warn("%s", to.p_path); rval = 1; } /* Some systems don't unmap on close(2). */ if (munmap(p, fs->st_size) < 0) { warn("%s", entp->fts_path); rval = 1; } } } else #endif { int skipholes = 0; struct stat tosb; if (!fstat(to_fd, &tosb) && S_ISREG(tosb.st_mode)) skipholes = 1; while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) { if (skipholes && memcmp(buf, zeroes, rcount) == 0) wcount = lseek(to_fd, rcount, SEEK_CUR) == -1 ? -1 : rcount; else wcount = write(to_fd, buf, rcount); if (rcount != wcount || wcount == -1) { warn("%s", to.p_path); rval = 1; break; } } if (skipholes && rcount >= 0) rcount = ftruncate(to_fd, fs->st_size); if (rcount < 0) { warn("%s", entp->fts_path); rval = 1; } } if (rval == 1) { (void)close(from_fd); (void)close(to_fd); return (1); } if (pflag && setfile(fs, to_fd)) rval = 1; /* * If the source was setuid or setgid, lose the bits unless the * copy is owned by the same user and group. */ #define RETAINBITS \ (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) if (!pflag && dne && fs->st_mode & (S_ISUID | S_ISGID) && fs->st_uid == myuid) { if (fstat(to_fd, &to_stat)) { warn("%s", to.p_path); rval = 1; } else if (fs->st_gid == to_stat.st_gid && fchmod(to_fd, fs->st_mode & RETAINBITS & ~myumask)) { warn("%s", to.p_path); rval = 1; } } (void)close(from_fd); if (close(to_fd)) { warn("%s", to.p_path); rval = 1; } return (rval); }