Пример #1
0
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");
}
Пример #2
0
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);
}
Пример #3
0
/**
 * 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);
}
Пример #4
0
/******************************************************************************
 * 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);
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
void outputfile(char *buf, char *orgbuf, char *ext)
{
    if (has_output_file)
        AddExt(buf, ext);
    else
        setfile(buf, orgbuf, ext);
}
Пример #8
0
/**
 * 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);
}
Пример #9
0
/**
 * 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);
}
Пример #10
0
/* 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);
}
Пример #11
0
Файл: xldmem.c Проект: 8l/csolve
/* 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);
}
Пример #12
0
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;
  }
}
Пример #13
0
Файл: liolib.c Проект: jeske/hz
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);
}
Пример #14
0
/*
 * 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);
}
Пример #15
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);
}
Пример #16
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);
}
Пример #17
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);
}
Пример #18
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);
  }

}
Пример #19
0
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);
}
Пример #20
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);
}
Пример #21
0
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);
}
Пример #22
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);
}
Пример #23
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;
}
Пример #24
0
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);
}
Пример #25
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;
}
Пример #26
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);
}
Пример #27
0
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;
}
Пример #28
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);
}
Пример #29
0
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);
}
Пример #30
0
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);
}