示例#1
0
void str_echo(int sockfd) {
    char line[MAXLINE];
    FILE *fpin;
    FILE *fpout;

    fpin = Fdopen(sockfd, "r");
    fpout = Fdopen(sockfd, "w");

    while (Fgets(line, MAXLINE, fpin) != NULL)
        Fputs(line, fpout);
}
示例#2
0
文件: pack.c 项目: nforro/rpm
/**
 * @todo Create transaction set *much* earlier.
 */
static rpmRC cpio_doio(FD_t fdo, Package pkg, const char * fmodeMacro,
			rpm_loff_t *archiveSize)
{
    char *failedFile = NULL;
    FD_t cfd;
    int fsmrc;

    (void) Fflush(fdo);
    cfd = Fdopen(fdDup(Fileno(fdo)), fmodeMacro);
    if (cfd == NULL)
	return RPMRC_FAIL;

    fsmrc = rpmPackageFilesArchive(pkg->cpioList, headerIsSource(pkg->header),
				   cfd, pkg->dpaths,
				   archiveSize, &failedFile);

    if (fsmrc) {
	char *emsg = rpmfileStrerror(fsmrc);
	if (failedFile)
	    rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
		   failedFile, emsg);
	else
	    rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"), emsg);
	free(emsg);
    }

    free(failedFile);
    Fclose(cfd);

    return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL;
}
示例#3
0
文件: pack.c 项目: ereshetova/rpm
/**
 * @todo Create transaction set *much* earlier.
 */
static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa, const char * fmodeMacro)
{
    char *failedFile = NULL;
    FD_t cfd;
    int fsmrc;

    (void) Fflush(fdo);
    cfd = Fdopen(fdDup(Fileno(fdo)), fmodeMacro);
    if (cfd == NULL)
	return RPMRC_FAIL;

    fsmrc = rpmPackageFilesArchive(csa->cpioList, headerIsSource(h), cfd,
		      &csa->cpioArchiveSize, &failedFile);

    if (fsmrc) {
	if (failedFile)
	    rpmlog(RPMLOG_ERR, _("create archive failed on file %s\n"), failedFile);
	else
	    rpmlog(RPMLOG_ERR, _("create archive failed\n"));
    }

    free(failedFile);
    Fclose(cfd);

    return (fsmrc == 0) ? RPMRC_OK : RPMRC_FAIL;
}
示例#4
0
文件: pack.c 项目: kaltsi/rpm
/**
 * @todo Create transaction set *much* earlier.
 */
static rpmRC cpio_doio(FD_t fdo, Header h, CSA_t csa,
		const char * fmodeMacro)
{
    rpmts ts = rpmtsCreate();
    rpmfi fi = csa->cpioList;
    rpmte te = NULL;
    rpmfs fs = NULL;
    char *failedFile = NULL;
    FD_t cfd;
    rpmRC rc = RPMRC_OK;
    int xx, i;

    {	char *fmode = rpmExpand(fmodeMacro, NULL);
	if (!(fmode && fmode[0] == 'w'))
	    fmode = xstrdup("w9.gzdio");
	(void) Fflush(fdo);
	cfd = Fdopen(fdDup(Fileno(fdo)), fmode);
	fmode = _free(fmode);
    }
    if (cfd == NULL)
	return RPMRC_FAIL;

    /* make up a transaction element for passing to fsm */
    rpmtsAddInstallElement(ts, h, NULL, 0, NULL);
    te = rpmtsElement(ts, 0);
    fs = rpmteGetFileStates(te);

    fi = rpmfiInit(fi, 0);
    while ((i = rpmfiNext(fi)) >= 0) {
	if (rpmfiFFlags(fi) & RPMFILE_GHOST)
	    rpmfsSetAction(fs, i, FA_SKIP);
	else
	    rpmfsSetAction(fs, i, FA_COPYOUT);
    }

    xx = fsmSetup(rpmfiFSM(fi), FSM_PKGBUILD, ts, te, fi, cfd,
		&csa->cpioArchiveSize, &failedFile);
    if (xx)
	rc = RPMRC_FAIL;
    (void) Fclose(cfd);
    xx = fsmTeardown(rpmfiFSM(fi));
    if (rc == RPMRC_OK && xx) rc = RPMRC_FAIL;

    if (rc) {
	if (failedFile)
	    rpmlog(RPMLOG_ERR, _("create archive failed on file %s: %s\n"),
		failedFile, cpioStrerror(rc));
	else
	    rpmlog(RPMLOG_ERR, _("create archive failed: %s\n"),
		cpioStrerror(rc));
      rc = RPMRC_FAIL;
    }
    rpmtsEmpty(ts);

    failedFile = _free(failedFile);
    ts = rpmtsFree(ts);

    return rc;
}
示例#5
0
文件: rpmfd-py.c 项目: Distrotech/rpm
static FD_t openFd(FD_t ofd, const char *mode)
{
    FD_t fd;
    Py_BEGIN_ALLOW_THREADS
    fd = Fdopen(ofd, mode);
    Py_END_ALLOW_THREADS;
    return fd;
}
示例#6
0
文件: rpmio.c 项目: akozumpl/rpm
FD_t Fopen(const char *path, const char *fmode)
{
    char stdio[20], other[20];
    const char *end = NULL;
    mode_t perms = 0666;
    int flags = 0;
    FD_t fd;

    if (path == NULL || fmode == NULL)
	return NULL;

    stdio[0] = '\0';
    cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, &flags);
    if (stdio[0] == '\0')
	return NULL;

    if (end == NULL || rstreq(end, "fdio")) {
if (_rpmio_debug)
fprintf(stderr, "*** Fopen fdio path %s fmode %s\n", path, fmode);
	fd = fdOpen(path, flags, perms);
	if (fdFileno(fd) < 0) {
	    if (fd) (void) fdClose(fd);
	    return NULL;
	}
    } else {
	/* XXX gzdio and bzdio here too */

	switch (urlIsURL(path)) {
	case URL_IS_HTTPS:
	case URL_IS_HTTP:
	case URL_IS_HKP:
	case URL_IS_PATH:
	case URL_IS_DASH:
	case URL_IS_FTP:
	case URL_IS_UNKNOWN:
if (_rpmio_debug)
fprintf(stderr, "*** Fopen ufdio path %s fmode %s\n", path, fmode);
	    fd = ufdOpen(path, flags, perms);
	    if (fd == NULL || !(fdFileno(fd) >= 0))
		return fd;
	    break;
	default:
if (_rpmio_debug)
fprintf(stderr, "*** Fopen WTFO path %s fmode %s\n", path, fmode);
	    return NULL;
	    break;
	}

    }

    if (fd)
	fd = Fdopen(fd, fmode);

    DBGIO(fd, (stderr, "==>\tFopen(\"%s\",%x,0%o) %s\n",
	  path, (unsigned)flags, (unsigned)perms, fdbg(fd)));

    return fd;
}
示例#7
0
文件: send.c 项目: mulichao/freebsd
/*
 * Prepend a header in front of the collected stuff
 * and return the new file.
 */
FILE *
infix(struct header *hp, FILE *fi)
{
	FILE *nfo, *nfi;
	int c, fd;
	char tempname[PATHSIZE];

	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.RsXXXXXXXXXX", tmpdir);
	if ((fd = mkstemp(tempname)) == -1 ||
	    (nfo = Fdopen(fd, "w")) == NULL) {
		warn("%s", tempname);
		return (fi);
	}
	if ((nfi = Fopen(tempname, "r")) == NULL) {
		warn("%s", tempname);
		(void)Fclose(nfo);
		(void)rm(tempname);
		return (fi);
	}
	(void)rm(tempname);
	(void)puthead(hp, nfo,
	    GTO|GSUBJECT|GCC|GBCC|GREPLYTO|GINREPLYTO|GNL|GCOMMA);
	c = getc(fi);
	while (c != EOF) {
		(void)putc(c, nfo);
		c = getc(fi);
	}
	if (ferror(fi)) {
		warnx("read");
		rewind(fi);
		return (fi);
	}
	(void)fflush(nfo);
	if (ferror(nfo)) {
		warn("%s", tempname);
		(void)Fclose(nfo);
		(void)Fclose(nfi);
		rewind(fi);
		return (fi);
	}
	(void)Fclose(nfo);
	(void)Fclose(fi);
	rewind(nfi);
	return (nfi);
}
示例#8
0
文件: collect.c 项目: UNGLinux/Obase
/*
 * Pipe the message through the command.
 * Old message is on stdin of command;
 * New message collected from stdout.
 * Sh -c must return 0 to accept the new message.
 */
void
mespipe(FILE *fp, char *cmd)
{
	FILE *nf;
	int fd;
	char *shell, tempname[PATHSIZE];
	struct sigaction oact;
	sigset_t oset;

	(void)ignoresig(SIGINT, &oact, &oset);
	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.ReXXXXXXXXXX", tmpdir);
	if ((fd = mkstemp(tempname)) == -1 ||
	    (nf = Fdopen(fd, "w+")) == NULL) {
		warn("%s", tempname);
		goto out;
	}
	(void)rm(tempname);
	/*
	 * stdin = current message.
	 * stdout = new message.
	 */
	shell = value("SHELL");
	if (run_command(shell,
	    0, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) {
		(void)Fclose(nf);
		goto out;
	}
	if (fsize(nf) == 0) {
		fprintf(stderr, "No bytes from \"%s\" !?\n", cmd);
		(void)Fclose(nf);
		goto out;
	}
	/*
	 * Take new files.
	 */
	(void)fseek(nf, 0L, SEEK_END);
	collf = nf;
	(void)Fclose(fp);
out:
	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
	(void)sigaction(SIGINT, &oact, NULL);
}
示例#9
0
/*
 * Pipe the message through the command.
 * Old message is on stdin of command;
 * New message collected from stdout.
 * Sh -c must return 0 to accept the new message.
 */
void
mespipe(FILE *fp, char cmd[])
{
	FILE *nf;
	int fd;
	sig_t sigint = signal(SIGINT, SIG_IGN);
	char *sh, tempname[PATHSIZE];

	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.ReXXXXXXXXXX", tmpdir);
	if ((fd = mkstemp(tempname)) == -1 ||
	    (nf = Fdopen(fd, "w+")) == NULL) {
		warn("%s", tempname);
		goto out;
	}
	(void)rm(tempname);
	/*
	 * stdin = current message.
	 * stdout = new message.
	 */
	if ((sh = value("SHELL")) == NULL)
		sh = _PATH_CSHELL;
	if (run_command(sh,
	    0, fileno(fp), fileno(nf), "-c", cmd, NULL) < 0) {
		(void)Fclose(nf);
		goto out;
	}
	if (fsize(nf) == 0) {
		fprintf(stderr, "No bytes from \"%s\" !?\n", cmd);
		(void)Fclose(nf);
		goto out;
	}
	/*
	 * Take new files.
	 */
	(void)fseeko(nf, (off_t)0, SEEK_END);
	collf = nf;
	(void)Fclose(fp);
out:
	(void)signal(SIGINT, sigint);
}
示例#10
0
/*
 * Run an editor on the file at "fpp" of "size" bytes,
 * and return a new file pointer.
 * Signals must be handled by the caller.
 * "Type" is 'e' for _PATH_EX, 'v' for _PATH_VI.
 */
FILE *
run_editor(FILE *fp, off_t size, int type, int readonly)
{
	FILE *nf = NULL;
	int t;
	time_t modtime;
	char *edit, tempname[PATHSIZE];
	struct stat statb;

	snprintf(tempname, sizeof(tempname), "%s/mail.ReXXXXXXXXXX", tmpdir);
	if ((t = mkstemp(tempname)) == -1 ||
	    (nf = Fdopen(t, "w")) == NULL) {
		warn("%s", tempname);
		goto out;
	}
	if (readonly && fchmod(t, 0400) == -1) {
		warn("%s", tempname);
		rm(tempname);
		goto out;
	}
	if (size >= 0)
		while (--size >= 0 && (t = getc(fp)) != EOF)
			putc(t, nf);
	else
		while ((t = getc(fp)) != EOF)
			putc(t, nf);
	fflush(nf);
	if (fstat(fileno(nf), &statb) < 0)
		modtime = 0;
	else
		modtime = statb.st_mtime;
	if (ferror(nf)) {
		Fclose(nf);
		warnx("%s", tempname);
		rm(tempname);
		nf = NULL;
		goto out;
	}
	if (Fclose(nf) < 0) {
		warn("%s", tempname);
		rm(tempname);
		nf = NULL;
		goto out;
	}
	nf = NULL;
	if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NULL)
		edit = type == 'e' ? _PATH_EX : _PATH_VI;
	if (run_command(edit, 0, -1, -1, tempname, NULL, NULL) < 0) {
		rm(tempname);
		goto out;
	}
	/*
	 * If in read only mode or file unchanged, just remove the editor
	 * temporary and return.
	 */
	if (readonly) {
		rm(tempname);
		goto out;
	}
	if (stat(tempname, &statb) < 0) {
		warn("%s", tempname);
		goto out;
	}
	if (modtime == statb.st_mtime) {
		rm(tempname);
		goto out;
	}
	/*
	 * Now switch to new file.
	 */
	if ((nf = Fopen(tempname, "a+")) == NULL) {
		warn("%s", tempname);
		rm(tempname);
		goto out;
	}
	rm(tempname);
out:
	return (nf);
}
示例#11
0
int main(int argc, char *argv[])
{
    FD_t fdi, fdo;
    Header h;
    char * rpmio_flags = NULL;
    rpmRC rc;
    FD_t gzdi;
    
    setprogname(argv[0]);	/* Retrofit glibc __progname */
    rpmReadConfigFiles(NULL, NULL);
    if (argc == 1)
	fdi = fdDup(STDIN_FILENO);
    else {
	if (rstreq(argv[1], "-h") || rstreq(argv[1], "--help")) {
	    fprintf(stderr, "Usage: rpm2cpio file.rpm\n");
	    exit(EXIT_FAILURE);
	}
	fdi = Fopen(argv[1], "r.ufdio");
    }

    if (Ferror(fdi)) {
	fprintf(stderr, "%s: %s: %s\n", argv[0],
		(argc == 1 ? "<stdin>" : argv[1]), Fstrerror(fdi));
	exit(EXIT_FAILURE);
    }
    fdo = fdDup(STDOUT_FILENO);

    {	rpmts ts = rpmtsCreate();
	rpmVSFlags vsflags = 0;

	/* XXX retain the ageless behavior of rpm2cpio */
        vsflags |= _RPMVSF_NODIGESTS;
        vsflags |= _RPMVSF_NOSIGNATURES;
        vsflags |= RPMVSF_NOHDRCHK;
	(void) rpmtsSetVSFlags(ts, vsflags);

	rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h);

	ts = rpmtsFree(ts);
    }

    switch (rc) {
    case RPMRC_OK:
    case RPMRC_NOKEY:
    case RPMRC_NOTTRUSTED:
	break;
    case RPMRC_NOTFOUND:
	fprintf(stderr, _("argument is not an RPM package\n"));
	exit(EXIT_FAILURE);
	break;
    case RPMRC_FAIL:
    default:
	fprintf(stderr, _("error reading header from package\n"));
	exit(EXIT_FAILURE);
	break;
    }

    /* Retrieve type of payload compression. */
    {	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
	rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
    }

    gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
    free(rpmio_flags);

    if (gzdi == NULL) {
	fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
	exit(EXIT_FAILURE);
    }

    rc = ufdCopy(gzdi, fdo);
    rc = (rc <= 0) ? EXIT_FAILURE : EXIT_SUCCESS;
    Fclose(fdo);

    Fclose(gzdi);	/* XXX gzdi == fdi */

    return rc;
}
示例#12
0
文件: build.c 项目: kaltsi/rpm
/*
 * @todo Single use by %%doc in files.c prevents static.
 */
rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name,
		const char *sb, int test)
{
    const char * rootDir = spec->rootDir;
    char *scriptName = NULL;
    char * buildDir = rpmGenPath(rootDir, "%{_builddir}", "");
    char * buildCmd = NULL;
    char * buildTemplate = NULL;
    char * buildPost = NULL;
    const char * mTemplate = NULL;
    const char * mCmd = NULL;
    const char * mPost = NULL;
    int argc = 0;
    const char **argv = NULL;
    FILE * fp = NULL;

    FD_t fd;
    FD_t xfd;
    pid_t pid;
    pid_t child;
    int status;
    rpmRC rc;
    
    switch (what) {
    case RPMBUILD_PREP:
	mTemplate = "%{__spec_prep_template}";
	mPost = "%{__spec_prep_post}";
	mCmd = "%{__spec_prep_cmd}";
	break;
    case RPMBUILD_BUILD:
	mTemplate = "%{__spec_build_template}";
	mPost = "%{__spec_build_post}";
	mCmd = "%{__spec_build_cmd}";
	break;
    case RPMBUILD_INSTALL:
	mTemplate = "%{__spec_install_template}";
	mPost = "%{__spec_install_post}";
	mCmd = "%{__spec_install_cmd}";
	break;
    case RPMBUILD_CHECK:
	mTemplate = "%{__spec_check_template}";
	mPost = "%{__spec_check_post}";
	mCmd = "%{__spec_check_cmd}";
	break;
    case RPMBUILD_CLEAN:
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    case RPMBUILD_RMBUILD:
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    case RPMBUILD_STRINGBUF:
    default:
	mTemplate = "%{___build_template}";
	mPost = "%{___build_post}";
	mCmd = "%{___build_cmd}";
	break;
    }

    if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
	rc = RPMRC_OK;
	goto exit;
    }
    
    fd = rpmMkTempFile(rootDir, &scriptName);
    if (fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
	rc = RPMRC_FAIL;
	goto exit;
    }

    if (fdGetFILE(fd) == NULL)
	xfd = Fdopen(fd, "w.fpio");
    else
	xfd = fd;

    if ((fp = fdGetFILE(xfd)) == NULL) {
	rc = RPMRC_FAIL;
	goto exit;
    }
    
    if (*rootDir == '\0') rootDir = "/";

    buildTemplate = rpmExpand(mTemplate, NULL);
    buildPost = rpmExpand(mPost, NULL);

    (void) fputs(buildTemplate, fp);

    if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
	fprintf(fp, "cd '%s'\n", spec->buildSubdir);

    if (what == RPMBUILD_RMBUILD) {
	if (spec->buildSubdir)
	    fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
    } else if (sb != NULL)
	fprintf(fp, "%s", sb);

    (void) fputs(buildPost, fp);
    
    (void) Fclose(xfd);

    if (test) {
	rc = RPMRC_OK;
	goto exit;
    }
    
    if (buildDir && buildDir[0] != '/') {
	rc = RPMRC_FAIL;
	goto exit;
    }

    buildCmd = rpmExpand(mCmd, " ", scriptName, NULL);
    (void) poptParseArgvString(buildCmd, &argc, &argv);

    rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);
    if (!(child = fork())) {
	/* NSPR messes with SIGPIPE, reset to default for the kids */
	signal(SIGPIPE, SIG_DFL);
	errno = 0;
	(void) execvp(argv[0], (char *const *)argv);

	rpmlog(RPMLOG_ERR, _("Exec of %s failed (%s): %s\n"),
		scriptName, name, strerror(errno));

	_exit(127); /* exit 127 for compatibility with bash(1) */
    }

    pid = waitpid(child, &status, 0);

    if (!WIFEXITED(status) || WEXITSTATUS(status)) {
	rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
		 scriptName, name);
	rc = RPMRC_FAIL;
    } else
	rc = RPMRC_OK;
    
exit:
    if (scriptName) {
	if (rc == RPMRC_OK)
	    (void) unlink(scriptName);
	scriptName = _free(scriptName);
    }
    argv = _free(argv);
    buildCmd = _free(buildCmd);
    buildTemplate = _free(buildTemplate);
    buildPost = _free(buildPost);
    buildDir = _free(buildDir);

    return rc;
}
示例#13
0
static int process_package(rpmts ts, char * filename)
{
    FD_t fdi;
    FD_t gzdi;
    Header h;
    int rc = 0;
    char * rpmio_flags = NULL;
    struct archive *a;
    struct archive_entry *entry;

    if (!strcmp(filename, "-")) {
	fdi = fdDup(STDIN_FILENO);
    } else {
	fdi = Fopen(filename, "r.ufdio");
    }

    if (Ferror(fdi)) {
	fprintf(stderr, "rpm2archive: %s: %s\n",
		filename, Fstrerror(fdi));
	exit(EXIT_FAILURE);
    }

    rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h);

    switch (rc) {
    case RPMRC_OK:
    case RPMRC_NOKEY:
    case RPMRC_NOTTRUSTED:
	break;
    case RPMRC_NOTFOUND:
	fprintf(stderr, _("argument is not an RPM package\n"));
	exit(EXIT_FAILURE);
	break;
    case RPMRC_FAIL:
    default:
	fprintf(stderr, _("error reading header from package\n"));
	exit(EXIT_FAILURE);
	break;
    }


    /* Retrieve payload size and compression type. */
    {	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
	rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
    }

    gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
    free(rpmio_flags);

    if (gzdi == NULL) {
	fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
	exit(EXIT_FAILURE);
    }

    rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER);
    rpmfi fi = rpmfiNewArchiveReader(gzdi, files, RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST);

    /* create archive */
    a = archive_write_new();
    archive_write_add_filter_gzip(a);
    archive_write_set_format_pax_restricted(a);

    if (!strcmp(filename, "-")) {
	if (isatty(STDOUT_FILENO)) {
	    fprintf(stderr, "Error: refusing to output archive data to a terminal.\n");
	    exit(EXIT_FAILURE);
	}
	archive_write_open_fd(a, STDOUT_FILENO);
    } else {
	char * outname = rstrscat(NULL, filename, ".tgz", NULL);
	archive_write_open_filename(a, outname);
	_free(outname);
	// XXX error handling
    }

    entry = archive_entry_new();

    char * buf = xmalloc(BUFSIZE);
    char * hardlink = NULL;

    rc = 0;
    while (rc >= 0) {
	rc = rpmfiNext(fi);
	if (rc == RPMERR_ITER_END) {
	    break;
	}

	rpm_mode_t mode = rpmfiFMode(fi);
	int nlink = rpmfiFNlink(fi);

	fill_archive_entry(a, entry, fi);

	if (nlink > 1) {
	    if (rpmfiArchiveHasContent(fi)) {
		_free(hardlink);
		hardlink = rstrscat(NULL, ".", rpmfiFN(fi), NULL);
	    } else {
		archive_entry_set_hardlink(entry, hardlink);
	    }
	}

	archive_write_header(a, entry);

	if (S_ISREG(mode) && (nlink == 1 || rpmfiArchiveHasContent(fi))) {
	    write_file_content(a, buf, fi);
	}
    }
    /* End of iteration is not an error */
    if (rc == RPMERR_ITER_END) {
	rc = 0;
    }

    _free(hardlink);

    Fclose(gzdi);	/* XXX gzdi == fdi */
    archive_entry_free(entry);
    archive_write_close(a);
    archive_write_free(a);
    buf = _free(buf);
    rpmfilesFree(files);
    rpmfiFree(fi);
    headerFree(h);
    return rc;
}
示例#14
0
/*
 * Save all of the undetermined messages at the top of "mbox"
 * Save all untouched messages back in the system mailbox.
 * Remove the system mailbox, if none saved there.
 */
void
quit(void)
{
    int mcount, p, modify, autohold, anystat, holdbit, nohold;
    FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
    struct message *mp;
    int c, fd;
    struct stat minfo;
    char *mbox, tempname[PATHSIZE];

    /*
     * If we are read only, we can't do anything,
     * so just return quickly.
     */
    if (readonly)
        return;
    /*
     * If editing (not reading system mail box), then do the work
     * in edstop()
     */
    if (edit) {
        edstop();
        return;
    }

    /*
     * See if there any messages to save in mbox.  If no, we
     * can save copying mbox to /tmp and back.
     *
     * Check also to see if any files need to be preserved.
     * Delete all untouched messages to keep them out of mbox.
     * If all the messages are to be preserved, just exit with
     * a message.
     */

    fbuf = Fopen(mailname, "r");
    if (fbuf == NULL)
        goto newmail;
    flock(fileno(fbuf), LOCK_EX);
    rbuf = NULL;
    if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
        printf("New mail has arrived.\n");
        snprintf(tempname, sizeof(tempname), "%s/mail.RqXXXXXXXXXX",
                 tmpdir);
        if ((fd = mkstemp(tempname)) == -1 ||
                (rbuf = Fdopen(fd, "w")) == NULL)
            goto newmail;
#ifdef APPEND
        fseeko(fbuf, mailsize, SEEK_SET);
        while ((c = getc(fbuf)) != EOF)
            putc(c, rbuf);
#else
        p = minfo.st_size - mailsize;
        while (p-- > 0) {
            c = getc(fbuf);
            if (c == EOF)
                goto newmail;
            putc(c, rbuf);
        }
#endif
        Fclose(rbuf);
        if ((rbuf = Fopen(tempname, "r")) == NULL)
            goto newmail;
        rm(tempname);
    }

    /*
     * Adjust the message flags in each message.
     */

    anystat = 0;
    autohold = value("hold") != NULL;
    holdbit = autohold ? MPRESERVE : MBOX;
    nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
    if (value("keepsave") != NULL)
        nohold &= ~MSAVED;
    for (mp = &message[0]; mp < &message[msgCount]; mp++) {
        if (mp->m_flag & MNEW) {
            mp->m_flag &= ~MNEW;
            mp->m_flag |= MSTATUS;
        }
        if (mp->m_flag & MSTATUS)
            anystat++;
        if ((mp->m_flag & MTOUCH) == 0)
            mp->m_flag |= MPRESERVE;
        if ((mp->m_flag & nohold) == 0)
            mp->m_flag |= holdbit;
    }
    modify = 0;
    if (Tflag != NULL) {
        if ((readstat = Fopen(Tflag, "w")) == NULL)
            Tflag = NULL;
    }
    for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
        if (mp->m_flag & MBOX)
            c++;
        if (mp->m_flag & MPRESERVE)
            p++;
        if (mp->m_flag & MODIFY)
            modify++;
        if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
            char *id;

            if ((id = hfield("article-id", mp)) != NULL)
                fprintf(readstat, "%s\n", id);
        }
    }
    if (Tflag != NULL)
        Fclose(readstat);
    if (p == msgCount && !modify && !anystat) {
        printf("Held %d message%s in %s\n",
               p, p == 1 ? "" : "s", mailname);
        Fclose(fbuf);
        return;
    }
    if (c == 0) {
        if (p != 0) {
            writeback(rbuf);
            Fclose(fbuf);
            return;
        }
        goto cream;
    }

    /*
     * Create another temporary file and copy user's mbox file
     * darin.  If there is no mbox, copy nothing.
     * If he has specified "append" don't copy his mailbox,
     * just copy saveable entries at the end.
     */

    mbox = expand("&");
    mcount = c;
    if (value("append") == NULL) {
        snprintf(tempname, sizeof(tempname), "%s/mail.RmXXXXXXXXXX",
                 tmpdir);
        if ((fd = mkstemp(tempname)) == -1 ||
                (obuf = Fdopen(fd, "w")) == NULL) {
            warn("%s", tempname);
            Fclose(fbuf);
            return;
        }
        if ((ibuf = Fopen(tempname, "r")) == NULL) {
            warn("%s", tempname);
            rm(tempname);
            Fclose(obuf);
            Fclose(fbuf);
            return;
        }
        rm(tempname);
        if ((abuf = Fopen(mbox, "r")) != NULL) {
            while ((c = getc(abuf)) != EOF)
                putc(c, obuf);
            Fclose(abuf);
        }
        if (ferror(obuf)) {
            warnx("%s", tempname);
            Fclose(ibuf);
            Fclose(obuf);
            Fclose(fbuf);
            return;
        }
        Fclose(obuf);
        close(open(mbox, O_CREAT | O_TRUNC | O_WRONLY, 0600));
        if ((obuf = Fopen(mbox, "r+")) == NULL) {
            warn("%s", mbox);
            Fclose(ibuf);
            Fclose(fbuf);
            return;
        }
    }
    if (value("append") != NULL) {
        if ((obuf = Fopen(mbox, "a")) == NULL) {
            warn("%s", mbox);
            Fclose(fbuf);
            return;
        }
        fchmod(fileno(obuf), 0600);
    }
    for (mp = &message[0]; mp < &message[msgCount]; mp++)
        if (mp->m_flag & MBOX)
            if (sendmessage(mp, obuf, saveignore, NULL) < 0) {
                warnx("%s", mbox);
                Fclose(ibuf);
                Fclose(obuf);
                Fclose(fbuf);
                return;
            }

    /*
     * Copy the user's old mbox contents back
     * to the end of the stuff we just saved.
     * If we are appending, this is unnecessary.
     */

    if (value("append") == NULL) {
        rewind(ibuf);
        c = getc(ibuf);
        while (c != EOF) {
            putc(c, obuf);
            if (ferror(obuf))
                break;
            c = getc(ibuf);
        }
        Fclose(ibuf);
    }
    fflush(obuf);
    trunc(obuf);
    if (ferror(obuf)) {
        warn("%s", mbox);
        Fclose(obuf);
        Fclose(fbuf);
        return;
    }
    Fclose(obuf);
    if (mcount == 1)
        printf("Saved 1 message in mbox\n");
    else
        printf("Saved %d messages in mbox\n", mcount);

    /*
     * Now we are ready to copy back preserved files to
     * the system mailbox, if any were requested.
     */

    if (p != 0) {
        writeback(rbuf);
        Fclose(fbuf);
        return;
    }

    /*
     * Finally, remove his /var/mail file.
     * If new mail has arrived, copy it back.
     */

cream:
    if (rbuf != NULL) {
        abuf = Fopen(mailname, "r+");
        if (abuf == NULL)
            goto newmail;
        while ((c = getc(rbuf)) != EOF)
            putc(c, abuf);
        Fclose(rbuf);
        trunc(abuf);
        Fclose(abuf);
        alter(mailname);
        Fclose(fbuf);
        return;
    }
    demail();
    Fclose(fbuf);
    return;

newmail:
    printf("Thou hast new mail.\n");
    if (fbuf != NULL)
        Fclose(fbuf);
}
示例#15
0
文件: fio.c 项目: ryo/netbsd-src
/*
 * Set up the input pointers while copying the mail file into /tmp.
 */
PUBLIC void
setptr(FILE *ibuf, off_t offset)
{
    int c;
    size_t len;
    char *cp;
    const char *cp2;
    struct message this;
    FILE *mestmp;
    int maybe, inhead;
    char linebuf[LINESIZE];
    int omsgCount;
#ifdef THREAD_SUPPORT
    int nmsgCount;
#else
# define nmsgCount	msgCount
#endif

    /* Get temporary file. */
    (void)snprintf(linebuf, LINESIZE, "%s/mail.XXXXXX", tmpdir);
    if ((c = mkstemp(linebuf)) == -1 ||
            (mestmp = Fdopen(c, "re+")) == NULL) {
        (void)fprintf(stderr, "mail: can't open %s\n", linebuf);
        exit(1);
    }
    (void)unlink(linebuf);

    nmsgCount = get_abs_msgCount();
    if (offset == 0) {
        nmsgCount = 0;
    } else {
        /* Seek into the file to get to the new messages */
        (void)fseeko(ibuf, offset, 0);
        /*
         * We need to make "offset" a pointer to the end of
         * the temp file that has the copy of the mail file.
         * If any messages have been edited, this will be
         * different from the offset into the mail file.
         */
        (void)fseek(otf, 0L, SEEK_END);
        offset = ftell(otf);
    }
    omsgCount = nmsgCount;
    maybe = 1;
    inhead = 0;
    message_init(&this, (off_t)0, MUSED|MNEW);

    for (;;) {
        if (fgets(linebuf, LINESIZE, ibuf) == NULL) {
            if (append(&this, mestmp))
                err(EXIT_FAILURE, "temporary file");
            makemessage(mestmp, omsgCount, nmsgCount);
            return;
        }
        len = strlen(linebuf);
        /*
         * Transforms lines ending in <CR><LF> to just <LF>.
         * This allows mail to be able to read Eudora mailboxes
         * that reside on a DOS partition.
         */
        if (len >= 2 && linebuf[len - 1] == '\n' &&
                linebuf[len - 2] == '\r') {
            linebuf[len - 2] = '\n';
            len--;
        }
        (void)fwrite(linebuf, sizeof(*linebuf), len, otf);
        if (ferror(otf))
            err(EXIT_FAILURE, "/tmp");
        if (len)
            linebuf[len - 1] = 0;
        if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
            nmsgCount++;
            if (append(&this, mestmp))
                err(EXIT_FAILURE, "temporary file");
            message_init(&this, offset, MUSED|MNEW);
            inhead = 1;
        } else if (linebuf[0] == 0) {
            inhead = 0;
        } else if (inhead) {
            for (cp = linebuf, cp2 = "status";; cp++) {
                if ((c = *cp2++) == 0) {
                    while (isspace((unsigned char)*cp++))
                        continue;
                    if (cp[-1] != ':')
                        break;
                    while ((c = *cp++) != '\0')
                        if (c == 'R')
                            this.m_flag |= MREAD;
                        else if (c == 'O')
                            this.m_flag &= ~MNEW;
                    inhead = 0;
                    break;
                }
                if (*cp != c && *cp != toupper(c))
                    break;
            }
        }
        offset += len;
        this.m_size += len;
        this.m_lines++;
        if (!inhead) {
            int lines_plus_wraps = 1;
            int linelen = (int)strlen(linebuf);

            if (screenwidth && (int)linelen > screenwidth) {
                lines_plus_wraps = linelen / screenwidth;
                if (linelen % screenwidth != 0)
                    ++lines_plus_wraps;
            }
            this.m_blines += lines_plus_wraps;
        }
        maybe = linebuf[0] == 0;
    }
}
示例#16
0
文件: collect.c 项目: UNGLinux/Obase
FILE *
collect(struct header *hp, int printheaders)
{
	FILE *fbuf;
	int lc, cc, fd, c, t, lastlong, rc, sig;
	int escape, eofcount, longline;
	char getsub;
	char linebuf[LINESIZE], tempname[PATHSIZE], *cp;

	collf = NULL;
	eofcount = 0;
	hadintr = 0;
	lastlong = 0;
	longline = 0;
	if ((cp = value("escape")) != NULL)
		escape = *cp;
	else
		escape = ESCAPE;
	noreset++;

	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.RsXXXXXXXXXX", tmpdir);
	if ((fd = mkstemp(tempname)) == -1 ||
	    (collf = Fdopen(fd, "w+")) == NULL) {
		warn("%s", tempname);
		goto err;
	}
	(void)rm(tempname);

	/*
	 * If we are going to prompt for a subject,
	 * refrain from printing a newline after
	 * the headers (since some people mind).
	 */
	t = GTO|GSUBJECT|GCC|GNL;
	getsub = 0;
	if (hp->h_subject == NULL && value("interactive") != NULL &&
	    (value("ask") != NULL || value("asksub") != NULL))
		t &= ~GNL, getsub++;
	if (printheaders) {
		puthead(hp, stdout, t);
		fflush(stdout);
	}
	if (getsub && gethfromtty(hp, GSUBJECT) == -1)
		goto err;

	if (0) {
cont:
		/* Come here for printing the after-suspend message. */
		if (isatty(0)) {
			puts("(continue)");
			fflush(stdout);
		}
	}
	for (;;) {
		c = readline(stdin, linebuf, LINESIZE, &sig);

		/* Act on any signal caught during readline() ignoring 'c' */
		switch (sig) {
		case 0:
			break;
		case SIGINT:
			if (collabort())
				goto err;
			continue;
		case SIGHUP:
			rewind(collf);
			savedeadletter(collf);
			/*
			 * Let's pretend nobody else wants to clean up,
			 * a true statement at this time.
			 */
			exit(1);
		default:
			/* Stopped due to job control */
			(void)kill(0, sig);
			goto cont;
		}

		/* No signal, check for error */
		if (c < 0) {
			if (value("interactive") != NULL &&
			    value("ignoreeof") != NULL && ++eofcount < 25) {
				puts("Use \".\" to terminate letter");
				continue;
			}
			break;
		}
		lastlong = longline;
		longline = (c == LINESIZE - 1);
		eofcount = 0;
		hadintr = 0;
		if (linebuf[0] == '.' && linebuf[1] == '\0' &&
		    value("interactive") != NULL && !lastlong &&
		    (value("dot") != NULL || value("ignoreeof") != NULL))
			break;
		if (linebuf[0] != escape || value("interactive") == NULL ||
		    lastlong) {
			if (putline(collf, linebuf, !longline) < 0)
				goto err;
			continue;
		}
		c = linebuf[1];
		switch (c) {
		default:
			/*
			 * On double escape, just send the single one.
			 * Otherwise, it's an error.
			 */
			if (c == escape) {
				if (putline(collf, &linebuf[1], !longline) < 0)
					goto err;
				else
					break;
			}
			puts("Unknown tilde escape.");
			break;
		case '!':
			/*
			 * Shell escape, send the balance of the
			 * line to sh -c.
			 */
			shell(&linebuf[2]);
			break;
		case ':':
		case '_':
			/*
			 * Escape to command mode, but be nice!
			 */
			execute(&linebuf[2], 1);
			goto cont;
		case '.':
			/*
			 * Simulate end of file on input.
			 */
			goto out;
		case 'q':
			/*
			 * Force a quit of sending mail.
			 * Act like an interrupt happened.
			 */
			hadintr++;
			collabort();
			fputs("Interrupt\n", stderr);
			goto err;
		case 'x':
			/*
			 * Force a quit of sending mail.
			 * Do not save the message.
			 */
			goto err;
		case 'h':
			/*
			 * Grab a bunch of headers.
			 */
			grabh(hp, GTO|GSUBJECT|GCC|GBCC);
			goto cont;
		case 't':
			/*
			 * Add to the To list.
			 */
			hp->h_to = cat(hp->h_to, extract(&linebuf[2], GTO));
			break;
		case 's':
			/*
			 * Set the Subject list.
			 */
			cp = &linebuf[2];
			while (isspace(*cp))
				cp++;
			hp->h_subject = savestr(cp);
			break;
		case 'c':
			/*
			 * Add to the CC list.
			 */
			hp->h_cc = cat(hp->h_cc, extract(&linebuf[2], GCC));
			break;
		case 'b':
			/*
			 * Add stuff to blind carbon copies list.
			 */
			hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC));
			break;
		case 'd':
			linebuf[2] = '\0';
			strlcat(linebuf, getdeadletter(), sizeof(linebuf));
			/* fall into . . . */
		case 'r':
		case '<':
			/*
			 * Invoke a file:
			 * Search for the file name,
			 * then open it and copy the contents to collf.
			 */
			cp = &linebuf[2];
			while (isspace(*cp))
				cp++;
			if (*cp == '\0') {
				puts("Interpolate what file?");
				break;
			}
			cp = expand(cp);
			if (cp == NULL)
				break;
			if (isdir(cp)) {
				printf("%s: Directory\n", cp);
				break;
			}
			if ((fbuf = Fopen(cp, "r")) == NULL) {
				warn("%s", cp);
				break;
			}
			printf("\"%s\" ", cp);
			fflush(stdout);
			lc = 0;
			cc = 0;
			while ((rc = readline(fbuf, linebuf, LINESIZE, NULL)) >= 0) {
				if (rc != LINESIZE - 1)
					lc++;
				if ((t = putline(collf, linebuf,
						 rc != LINESIZE-1)) < 0) {
					(void)Fclose(fbuf);
					goto err;
				}
				cc += t;
			}
			(void)Fclose(fbuf);
			printf("%d/%d\n", lc, cc);
			break;
		case 'w':
			/*
			 * Write the message on a file.
			 */
			cp = &linebuf[2];
			while (*cp == ' ' || *cp == '\t')
				cp++;
			if (*cp == '\0') {
				fputs("Write what file!?\n", stderr);
				break;
			}
			if ((cp = expand(cp)) == NULL)
				break;
			rewind(collf);
			exwrite(cp, collf, 1);
			break;
		case 'm':
		case 'M':
		case 'f':
		case 'F':
			/*
			 * Interpolate the named messages, if we
			 * are in receiving mail mode.  Does the
			 * standard list processing garbage.
			 * If ~f is given, we don't shift over.
			 */
			if (forward(linebuf + 2, collf, tempname, c) < 0)
				goto err;
			goto cont;
		case '?':
			if ((fbuf = Fopen(_PATH_TILDE, "r")) == NULL) {
				warn(_PATH_TILDE);
				break;
			}
			while ((t = getc(fbuf)) != EOF)
				(void)putchar(t);
			(void)Fclose(fbuf);
			break;
		case 'p':
			/*
			 * Print out the current state of the
			 * message without altering anything.
			 */
			rewind(collf);
			puts("-------\nMessage contains:");
			puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
			while ((t = getc(collf)) != EOF)
				(void)putchar(t);
			goto cont;
		case '|':
			/*
			 * Pipe message through command.
			 * Collect output as new message.
			 */
			rewind(collf);
			mespipe(collf, &linebuf[2]);
			goto cont;
		case 'v':
		case 'e':
			/*
			 * Edit the current message.
			 * 'e' means to use EDITOR
			 * 'v' means to use VISUAL
			 */
			rewind(collf);
			mesedit(collf, c);
			goto cont;
		}
	}

	if (value("interactive") != NULL) {
		if (value("askcc") != NULL || value("askbcc") != NULL) {
			if (value("askcc") != NULL) {
				if (gethfromtty(hp, GCC) == -1)
					goto err;
			}
			if (value("askbcc") != NULL) {
				if (gethfromtty(hp, GBCC) == -1)
					goto err;
			}
		} else {
			puts("EOT");
			(void)fflush(stdout);
		}
	}
	goto out;
err:
	if (collf != NULL) {
		(void)Fclose(collf);
		collf = NULL;
	}
out:
	if (collf != NULL)
		rewind(collf);
	noreset--;
	return(collf);
}
示例#17
0
文件: rpm2cpio.c 项目: xrg/RPM
int main(int argc, char *argv[])
{
    FD_t fdi, fdo;
    Header h;
    char * rpmio_flags;
    rpmRC rc;
    FD_t gzdi;
    
    setprogname(argv[0]);	/* Retrofit glibc __progname */
    if (argc == 1)
	fdi = fdDup(STDIN_FILENO);
    else
	fdi = Fopen(argv[1], "r.ufdio");

    if (Ferror(fdi)) {
	fprintf(stderr, "%s: %s: %s\n", argv[0],
		(argc == 1 ? "<stdin>" : argv[1]), Fstrerror(fdi));
	exit(EXIT_FAILURE);
    }
    fdo = fdDup(STDOUT_FILENO);
    rpmReadConfigFiles(NULL, NULL);

    {	rpmts ts = rpmtsCreate();
	rpmVSFlags vsflags = 0;

	/* XXX retain the ageless behavior of rpm2cpio */
        vsflags |= _RPMVSF_NODIGESTS;
        vsflags |= _RPMVSF_NOSIGNATURES;
        vsflags |= RPMVSF_NOHDRCHK;
	(void) rpmtsSetVSFlags(ts, vsflags);

	     /* LCL: segfault */
	rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h);

	ts = rpmtsFree(ts);
    }

    switch (rc) {
    case RPMRC_OK:
    case RPMRC_NOKEY:
    case RPMRC_NOTTRUSTED:
	break;
    case RPMRC_NOTFOUND:
	fprintf(stderr, _("argument is not an RPM package\n"));
	exit(EXIT_FAILURE);
	break;
    case RPMRC_FAIL:
    default:
	fprintf(stderr, _("error reading header from package\n"));
	exit(EXIT_FAILURE);
	break;
    }

    /* Retrieve type of payload compression. */
    {	const char * payload_compressor = NULL;
	struct rpmtd_s pc;

	headerGet(h, RPMTAG_PAYLOADCOMPRESSOR, &pc, HEADERGET_DEFAULT);
	payload_compressor = rpmtdGetString(&pc);
	if (!payload_compressor)
	    payload_compressor = "gzip";
	
	if (!strcmp(payload_compressor, "gzip"))
	    rpmio_flags = "r.gzdio";
	if (!strcmp(payload_compressor, "bzip2"))
	    rpmio_flags = "r.bzdio";
	if (!strcmp(payload_compressor, "lzma"))
	    rpmio_flags = "r.lzdio";
	rpmtdFreeData(&pc);
    }

    gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
    if (gzdi == NULL) {
	fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
	exit(EXIT_FAILURE);
    }

    rc = ufdCopy(gzdi, fdo);
    rc = (rc <= 0) ? EXIT_FAILURE : EXIT_SUCCESS;
    Fclose(fdo);

    Fclose(gzdi);	/* XXX gzdi == fdi */

    return rc;
}
示例#18
0
文件: quit.c 项目: ajinkya93/OpenBSD
/*
 * Terminate an editing session by attempting to write out the user's
 * file from the temporary.  Save any new stuff appended to the file.
 */
int
edstop(void)
{
	int gotcha, c;
	struct message *mp;
	FILE *obuf, *ibuf;
	struct stat statb;
	char tempname[PATHSIZE];

	if (readonly)
		return(0);
	holdsigs();
	for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
		if (mp->m_flag & MNEW) {
			mp->m_flag &= ~MNEW;
			mp->m_flag |= MSTATUS;
		}
		if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
			gotcha++;
	}
	if (!gotcha)
		goto done;
	ibuf = NULL;
	if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
		int fd;

		(void)snprintf(tempname, sizeof(tempname), "%s/mbox.XXXXXXXXXX",
		    tmpdir);
		if ((fd = mkstemp(tempname)) == -1 ||
		    (obuf = Fdopen(fd, "w")) == NULL) {
			warn("%s", tempname);
			if (fd != -1)
				close(fd);
			relsesigs();
			return(-1);
		}
		if ((ibuf = Fopen(mailname, "r")) == NULL) {
			warn("%s", mailname);
			(void)Fclose(obuf);
			(void)rm(tempname);
			relsesigs();
			return(-1);
		}
		fseek(ibuf, (long)mailsize, SEEK_SET);
		while ((c = getc(ibuf)) != EOF)
			(void)putc(c, obuf);
		(void)Fclose(ibuf);
		(void)Fclose(obuf);
		if ((ibuf = Fopen(tempname, "r")) == NULL) {
			warn("%s", tempname);
			(void)rm(tempname);
			relsesigs();
			return(-1);
		}
		(void)rm(tempname);
	}
	printf("\"%s\" ", mailname);
	fflush(stdout);
	if ((obuf = Fopen(mailname, "r+")) == NULL) {
		warn("%s", mailname);
		relsesigs();
		return(-1);
	}
	trunc(obuf);
	c = 0;
	for (mp = &message[0]; mp < &message[msgCount]; mp++) {
		if ((mp->m_flag & MDELETED) != 0)
			continue;
		c++;
		if (sendmessage(mp, obuf, NULL, NULL) < 0) {
			warn("%s", mailname);
			relsesigs();
			return(-1);
		}
	}
	gotcha = (c == 0 && ibuf == NULL);
	if (ibuf != NULL) {
		while ((c = getc(ibuf)) != EOF)
			(void)putc(c, obuf);
		(void)Fclose(ibuf);
	}
	fflush(obuf);
	if (ferror(obuf)) {
		warn("%s", mailname);
		relsesigs();
		return(-1);
	}
	(void)Fclose(obuf);
	if (gotcha) {
		(void)rm(mailname);
		puts("removed");
	} else
		puts("complete");
	fflush(stdout);

done:
	relsesigs();
	return(0);
}
示例#19
0
/*
 * explode source RPM into the current directory
 * use filters to skip packages and files we do not need
 */
int explodeRPM(const char *source,
        filterfunc filter,
        dependencyfunc provides,
        dependencyfunc deps,
        void* userptr)
{
    char buffer[BUFFERSIZE+1]; /* make space for trailing \0 */
    FD_t fdi;
    Header h;
    char * rpmio_flags = NULL;
    rpmRC rc;
    FD_t gzdi;
    struct archive *cpio;
    struct archive_entry *cpio_entry;
    struct cpio_mydata cpio_mydata;

    rpmts ts;
    rpmVSFlags vsflags;
    const char *compr;

    if (strcmp(source, "-") == 0)
        fdi = fdDup(STDIN_FILENO);
    else
        fdi = Fopen(source, "r.ufdio");

    if (Ferror(fdi)) {
        const char *srcname = (strcmp(source, "-") == 0) ? "<stdin>" : source;
        logMessage(ERROR, "%s: %s\n", srcname, Fstrerror(fdi));
        return EXIT_FAILURE;
    }
    rpmReadConfigFiles(NULL, NULL);

    /* Initialize RPM transaction */
    ts = rpmtsCreate();
    vsflags = 0;

    /* Do not check digests, signatures or headers */
    vsflags |= _RPMVSF_NODIGESTS;
    vsflags |= _RPMVSF_NOSIGNATURES;
    vsflags |= RPMVSF_NOHDRCHK;
    (void) rpmtsSetVSFlags(ts, vsflags);

    rc = rpmReadPackageFile(ts, fdi, "rpm2dir", &h);

    ts = rpmtsFree(ts);

    switch (rc) {
        case RPMRC_OK:
        case RPMRC_NOKEY:
        case RPMRC_NOTTRUSTED:
            break;
        case RPMRC_NOTFOUND:
            logMessage(ERROR, "%s is not an RPM package", source);
            return EXIT_FAILURE;
            break;
        case RPMRC_FAIL:
        default:
            logMessage(ERROR, "error reading header from %s package\n", source);
            return EXIT_FAILURE;
            break;
    }

    /* Retrieve all dependencies and run them through deps function */
    while (deps) {
        struct rpmtd_s td;
        const char *depname;

        if (!headerGet(h, RPMTAG_REQUIRENAME, &td, HEADERGET_MINMEM))
            break;

        /* iterator */
        while ((depname = rpmtdNextString(&td))) {
            if (deps(depname, userptr)) {
                Fclose(fdi);
                return EXIT_BADDEPS;
            }
        }
        rpmtdFreeData(&td);
        break;
    }

    /* Retrieve all provides and run them through provides function */
    while (provides) {
        struct rpmtd_s td;
        const char *depname;
        int found = 0;

        if (!headerGet(h, RPMTAG_PROVIDES, &td, HEADERGET_MINMEM))
            break;

        /* iterator */
        while ((depname = rpmtdNextString(&td))) {
            if (!provides(depname, userptr)) {
                found++;
            }
        }
        rpmtdFreeData(&td);
        if (found<=0)
            return EXIT_BADDEPS;
        break;
    }

    /* Retrieve type of payload compression. */
    compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
    if (compr && strcmp(compr, "gzip")) {
        checked_asprintf(&rpmio_flags, "r.%sdio", compr);
    }
    else {
        checked_asprintf(&rpmio_flags, "r.gzdio");
    }

    /* Open uncompressed cpio stream */
    gzdi = Fdopen(fdi, rpmio_flags);
    free(rpmio_flags);

    if (gzdi == NULL) {
        logMessage(ERROR, "cannot re-open payload: %s\n", Fstrerror(gzdi));
        return EXIT_FAILURE;
    }

    /* initialize cpio decompressor */
    cpio = archive_read_new();
    if (cpio==NULL) {
        Fclose(gzdi);
        return -1;
    }

    cpio_mydata.gzdi = gzdi;
    cpio_mydata.buffer = buffer;
    archive_read_support_compression_all(cpio);
    archive_read_support_format_all(cpio);
    rc = archive_read_open(cpio, &cpio_mydata, NULL, rpm_myread, rpm_myclose);

    /* check the status of archive_open */
    if (rc != ARCHIVE_OK){
        Fclose(gzdi);
        return -1;
    }

    /* read all files in cpio archive */
    while ((rc = archive_read_next_header(cpio, &cpio_entry)) == ARCHIVE_OK){
        const struct stat *fstat;
        int64_t fsize;
        const char* filename;
        int needskip = 1; /* do we need to read the data to get to the next header? */
        int offset = 0;
        int towrite = 0;

        filename = archive_entry_pathname(cpio_entry);
        fstat = archive_entry_stat(cpio_entry);
        fsize = archive_entry_size(cpio_entry);

        /* Strip leading slashes */
        while (filename[offset] == '/')
            offset+=1;

        /* Strip leading ./ */
        while (filename[offset] == '.' && filename[offset+1] == '/')
            offset+=2;

        /* Other file type - we do not care except special cases */
        if (!S_ISREG(fstat->st_mode))
            towrite = 1;
        else
            towrite = 2;

        if (filter && filter(filename+offset, fstat, userptr)) {
            /* filter this file */
            towrite = 0;
        }

        /* Create directories */
        char* dirname = strdup(filename+offset);

        /* If the dup fails, let's hope the dirs already exist */
        if (dirname){
            char* dirptr = dirname;
            while (dirptr && *dirptr) {
                dirptr = strchr(dirptr, '/');
                if (dirptr) {
                    *dirptr = 0;
                    mkdir(dirname, 0700);
                    *dirptr = '/';
                    dirptr++;
                }
            }
            free(dirname);
        }

        /* Regular file */
        if (towrite>=2) {
            FILE *fdout = fopen(filename+offset, "w");

            if (fdout==NULL){
                rc = 33;
                break;
            }
            
            rc = archive_read_data_into_fd(cpio, fileno(fdout));
            if (rc!=ARCHIVE_OK) {
                /* XXX We didn't get the file.. well.. */
                needskip = 0;
            } else {
                needskip = 0;
                fclose(fdout);
            }
        }

        /* symlink, we assume that the path contained in symlink
         * is shorter than BUFFERSIZE */
        while (towrite && S_ISLNK(fstat->st_mode)) {
            char symlinkbuffer[BUFFERSIZE-1];

            needskip = 0;
            if ((rc = archive_read_data(cpio, symlinkbuffer, fsize))!=ARCHIVE_OK) {
                /* XXX We didn't get the file.. well.. */
                break;
            }

            if (symlink(buffer, filename+offset)) {
                logMessage(ERROR, "Failed to create symlink %s -> %s", filename+offset, buffer);
            }

            break;
        }

        if(needskip)
            archive_read_data_skip(cpio);
    }

    archive_read_finish(cpio);

    return rc != ARCHIVE_OK;
}
示例#20
0
/*
 * @todo Single use by %%doc in files.c prevents static.
 */
rpmRC doScript(Spec spec, int what, const char *name, rpmiob iob, int test)
{
    const char * rootURL = spec->rootURL;
    const char * rootDir;
    const char * scriptName = NULL;
    const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
    const char * buildScript;
    const char * buildCmd = NULL;
    const char * buildTemplate = NULL;
    const char * buildPost = NULL;
    const char * mTemplate = NULL;
    const char * mCmd = NULL;
    const char * mPost = NULL;
    int argc = 0;
    const char **argv = NULL;
    FILE * fp = NULL;
    urlinfo u = NULL;
    rpmop op = NULL;
    int ix = -1;

    FD_t fd;
    FD_t xfd;
    int status;
    rpmRC rc;
    size_t i;

    switch (what) {
    case RPMBUILD_PREP:
	name = "%prep";
	iob = spec->prep;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_PREP;
	mTemplate = "%{__spec_prep_template}";
	mPost = "%{__spec_prep_post}";
	mCmd = "%{__spec_prep_cmd}";
	break;
    case RPMBUILD_BUILD:
	name = "%build";
	iob = spec->build;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_BUILD;
	mTemplate = "%{__spec_build_template}";
	mPost = "%{__spec_build_post}";
	mCmd = "%{__spec_build_cmd}";
	break;
    case RPMBUILD_INSTALL:
	name = "%install";
	iob = spec->install;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_INSTALL;
	mTemplate = "%{__spec_install_template}";
	mPost = "%{__spec_install_post}";
	mCmd = "%{__spec_install_cmd}";
	break;
    case RPMBUILD_CHECK:
	name = "%check";
	iob = spec->check;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_CHECK;
	mTemplate = "%{__spec_check_template}";
	mPost = "%{__spec_check_post}";
	mCmd = "%{__spec_check_cmd}";
	break;
    case RPMBUILD_CLEAN:
	name = "%clean";
	iob = spec->clean;
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    case RPMBUILD_RMBUILD:
	name = "--clean";
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    /* support "%track" script/section */
    case RPMBUILD_TRACK:
	name = "%track";
	iob = NULL;
	if (spec->foo)
	for (i = 0; i < spec->nfoo; i++) {
	    if (spec->foo[i].str == NULL || spec->foo[i].iob == NULL)
		continue;
	    if (xstrcasecmp(spec->foo[i].str, "track"))
		continue;
	    iob = spec->foo[i].iob;
	    /*@loopbreak@*/ break;
	}
	mTemplate = "%{__spec_track_template}";
	mPost = "%{__spec_track_post}";
	mCmd = "%{__spec_track_cmd}";
	break;
    case RPMBUILD_STRINGBUF:
    default:
	mTemplate = "%{___build_template}";
	mPost = "%{___build_post}";
	mCmd = "%{___build_cmd}";
	break;
    }

assert(name != NULL);

    if ((what != RPMBUILD_RMBUILD) && iob == NULL) {
	rc = RPMRC_OK;
	goto exit;
    }

    if (rpmTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
	rc = RPMRC_FAIL;
	goto exit;
    }

    if (fdGetFp(fd) == NULL)
	xfd = Fdopen(fd, "w.fpio");
    else
	xfd = fd;

    /*@-type@*/ /* FIX: cast? */
    if ((fp = fdGetFp(xfd)) == NULL) {
	rc = RPMRC_FAIL;
	goto exit;
    }
    /*@=type@*/

    (void) urlPath(rootURL, &rootDir);
    if (*rootDir == '\0') rootDir = "/";

    (void) urlPath(scriptName, &buildScript);

    buildTemplate = rpmExpand(mTemplate, NULL);
    buildPost = rpmExpand(mPost, NULL);

    (void) fputs(buildTemplate, fp);

    /* support "%track" script/section */
    if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir && what != RPMBUILD_TRACK)
	fprintf(fp, "cd '%s'\n", spec->buildSubdir);

    if (what == RPMBUILD_RMBUILD) {
	if (spec->buildSubdir)
	    fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
    } else if (iob != NULL)
	fprintf(fp, "%s", rpmiobStr(iob));

    (void) fputs(buildPost, fp);

    (void) Fclose(xfd);

    if (test) {
	rc = RPMRC_OK;
	goto exit;
    }

    if (buildDirURL && buildDirURL[0] != '/' &&
	(urlSplit(buildDirURL, &u) != 0)) {
	rc = RPMRC_FAIL;
	goto exit;
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
	addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
	if (strcmp(rootDir, "/"))
	    addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    buildCmd = rpmExpand(mCmd, " ", buildScript, NULL);
    (void) poptParseArgvString(buildCmd, &argc, &argv);

    if (what != RPMBUILD_TRACK)		/* support "%track" script/section */
	rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);

    /* Run the script with a stopwatch. */
    if (op != NULL)
	(void) rpmswEnter(op, 0);

    status = rpmsqExecve(argv);
    if (ix >= 0 && ix < RPMSCRIPT_MAX)
	spec->sstates[ix] =
	    (RPMSCRIPT_STATE_EXEC | RPMSCRIPT_STATE_REAPED) | (status & 0xffff);

    if (!WIFEXITED(status) || WEXITSTATUS(status)) {
	rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
		 scriptName, name);
	rc = RPMRC_FAIL;
    } else
	rc = RPMRC_OK;

    if (op != NULL) {
	static unsigned int scale = 1000;
	(void) rpmswExit(op, 0);
	if (ix >= 0 && ix < RPMSCRIPT_MAX)
	    spec->smetrics[ix] += op->usecs / scale;
    }

exit:
    if (scriptName) {
#if defined(RPM_VENDOR_OPENPKG) /* always-remove-tempfiles */
	/* Unconditionally remove temporary files ("rpm-tmp.XXXXX") which
	   were generated for the executed scripts. In OpenPKG we run the
	   scripts in debug mode ("set -x") anyway, so we never need to
	   see the whole generated script -- not even if it breaks.  Instead
	   we would just have temporary files staying around forever. */
#else
	if (rc == RPMRC_OK)
#endif
	    (void) Unlink(scriptName);
	scriptName = _free(scriptName);
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	delMacro(spec->macros, "_remsh");
	delMacro(spec->macros, "_remhost");
	if (strcmp(rootDir, "/"))
	    delMacro(spec->macros, "_remroot");
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    argv = _free(argv);
    buildCmd = _free(buildCmd);
    buildTemplate = _free(buildTemplate);
    buildPost = _free(buildPost);
    buildDirURL = _free(buildDirURL);
    return rc;
}
示例#21
0
FILE *
collect(struct header *hp, int printheaders)
{
	FILE *fbuf;
	int lc, cc, escape, eofcount, fd, c, t;
	char linebuf[LINESIZE], tempname[PATHSIZE], *cp, getsub;
	sigset_t nset;
	int longline, lastlong, rc;	/* So we don't make 2 or more lines
					   out of a long input line. */

	collf = NULL;
	/*
	 * Start catching signals from here, but we're still die on interrupts
	 * until we're in the main loop.
	 */
	(void)sigemptyset(&nset);
	(void)sigaddset(&nset, SIGINT);
	(void)sigaddset(&nset, SIGHUP);
	(void)sigprocmask(SIG_BLOCK, &nset, NULL);
	if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN)
		(void)signal(SIGINT, collint);
	if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN)
		(void)signal(SIGHUP, collhup);
	savetstp = signal(SIGTSTP, collstop);
	savettou = signal(SIGTTOU, collstop);
	savettin = signal(SIGTTIN, collstop);
	if (setjmp(collabort) || setjmp(colljmp)) {
		(void)rm(tempname);
		goto err;
	}
	(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);

	noreset++;
	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.RsXXXXXXXXXX", tmpdir);
	if ((fd = mkstemp(tempname)) == -1 ||
	    (collf = Fdopen(fd, "w+")) == NULL) {
		warn("%s", tempname);
		goto err;
	}
	(void)rm(tempname);

	/*
	 * If we are going to prompt for a subject,
	 * refrain from printing a newline after
	 * the headers (since some people mind).
	 */
	t = GTO|GSUBJECT|GCC|GNL;
	getsub = 0;
	if (hp->h_subject == NULL && value("interactive") != NULL &&
	    (value("ask") != NULL || value("asksub") != NULL))
		t &= ~GNL, getsub++;
	if (printheaders) {
		puthead(hp, stdout, t);
		(void)fflush(stdout);
	}
	if ((cp = value("escape")) != NULL)
		escape = *cp;
	else
		escape = ESCAPE;
	eofcount = 0;
	hadintr = 0;
	lastlong = 0;
	longline = 0;

	if (!setjmp(colljmp)) {
		if (getsub)
			grabh(hp, GSUBJECT);
	} else {
		/*
		 * Come here for printing the after-signal message.
		 * Duplicate messages won't be printed because
		 * the write is aborted if we get a SIGTTOU.
		 */
cont:
		if (hadintr) {
			(void)fflush(stdout);
			fprintf(stderr,
			"\n(Interrupt -- one more to kill letter)\n");
		} else {
			printf("(continue)\n");
			(void)fflush(stdout);
		}
	}
	for (;;) {
		colljmp_p = 1;
		c = readline(stdin, linebuf, LINESIZE);
		colljmp_p = 0;
		if (c < 0) {
			if (value("interactive") != NULL &&
			    value("ignoreeof") != NULL && ++eofcount < 25) {
				printf("Use \".\" to terminate letter\n");
				continue;
			}
			break;
		}
		lastlong = longline;
		longline = c == LINESIZE - 1;
		eofcount = 0;
		hadintr = 0;
		if (linebuf[0] == '.' && linebuf[1] == '\0' &&
		    value("interactive") != NULL && !lastlong &&
		    (value("dot") != NULL || value("ignoreeof") != NULL))
			break;
		if (linebuf[0] != escape || value("interactive") == NULL ||
		    lastlong) {
			if (putline(collf, linebuf, !longline) < 0)
				goto err;
			continue;
		}
		c = linebuf[1];
		switch (c) {
		default:
			/*
			 * On double escape, just send the single one.
			 * Otherwise, it's an error.
			 */
			if (c == escape) {
				if (putline(collf, &linebuf[1], !longline) < 0)
					goto err;
				else
					break;
			}
			printf("Unknown tilde escape.\n");
			break;
		case 'C':
			/*
			 * Dump core.
			 */
			core();
			break;
		case '!':
			/*
			 * Shell escape, send the balance of the
			 * line to sh -c.
			 */
			shell(&linebuf[2]);
			break;
		case ':':
		case '_':
			/*
			 * Escape to command mode, but be nice!
			 */
			execute(&linebuf[2], 1);
			goto cont;
		case '.':
			/*
			 * Simulate end of file on input.
			 */
			goto out;
		case 'q':
			/*
			 * Force a quit of sending mail.
			 * Act like an interrupt happened.
			 */
			hadintr++;
			collint(SIGINT);
			exit(1);
		case 'x':
			/*
			 * Exit, do not save in dead.letter.
			 */
			goto err;
		case 'h':
			/*
			 * Grab a bunch of headers.
			 */
			grabh(hp, GTO|GSUBJECT|GCC|GBCC);
			goto cont;
		case 't':
			/*
			 * Add to the To list.
			 */
			hp->h_to = cat(hp->h_to, extract(&linebuf[2], GTO));
			break;
		case 's':
			/*
			 * Set the Subject line.
			 */
			cp = &linebuf[2];
			while (isspace((unsigned char)*cp))
				cp++;
			hp->h_subject = savestr(cp);
			break;
		case 'R':
			/*
			 * Set the Reply-To line.
			 */
			cp = &linebuf[2];
			while (isspace((unsigned char)*cp))
				cp++;
			hp->h_replyto = savestr(cp);
			break;
		case 'c':
			/*
			 * Add to the CC list.
			 */
			hp->h_cc = cat(hp->h_cc, extract(&linebuf[2], GCC));
			break;
		case 'b':
			/*
			 * Add to the BCC list.
			 */
			hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC));
			break;
		case 'i':
		case 'A':
		case 'a':
			/*
			 * Insert named variable in message.
			 */
			switch(c) {
				case 'i':
					cp = &linebuf[2];
					while(isspace((unsigned char)*cp))
						cp++;
					break;
				case 'a':
					cp = "sign";
					break;
				case 'A':
					cp = "Sign";
					break;
				default:
					goto err;
			}

			if(*cp != '\0' && (cp = value(cp)) != NULL) {
				printf("%s\n", cp);
				if(putline(collf, cp, 1) < 0)
					goto err;
			}

			break;
		case 'd':
			/*
			 * Read in the dead letter file.
			 */
			if (strlcpy(linebuf + 2, getdeadletter(),
				sizeof(linebuf) - 2)
			    >= sizeof(linebuf) - 2) {
				printf("Line buffer overflow\n");
				break;
			}
			/* FALLTHROUGH */
		case 'r':
		case '<':
			/*
			 * Invoke a file:
			 * Search for the file name,
			 * then open it and copy the contents to collf.
			 */
			cp = &linebuf[2];
			while (isspace((unsigned char)*cp))
				cp++;
			if (*cp == '\0') {
				printf("Interpolate what file?\n");
				break;
			}
			cp = expand(cp);
			if (cp == NULL)
				break;
			if (*cp == '!') {
				/*
				 * Insert stdout of command.
				 */
				char *sh;
				int nullfd, tempfd, rc;
				char tempname2[PATHSIZE];

				if ((nullfd = open(_PATH_DEVNULL, O_RDONLY, 0))
				    == -1) {
					warn(_PATH_DEVNULL);
					break;
				}

				(void)snprintf(tempname2, sizeof(tempname2),
				    "%s/mail.ReXXXXXXXXXX", tmpdir);
				if ((tempfd = mkstemp(tempname2)) == -1 ||
				    (fbuf = Fdopen(tempfd, "w+")) == NULL) {
					warn("%s", tempname2);
					break;
				}
				(void)unlink(tempname2);

				if ((sh = value("SHELL")) == NULL)
					sh = _PATH_CSHELL;

				rc = run_command(sh, 0, nullfd, fileno(fbuf),
				    "-c", cp+1, NULL);

				close(nullfd);

				if (rc < 0) {
					(void)Fclose(fbuf);
					break;
				}

				if (fsize(fbuf) == 0) {
					fprintf(stderr,
					    "No bytes from command \"%s\"\n",
					    cp+1);
					(void)Fclose(fbuf);
					break;
				}

				rewind(fbuf);
			} else if (isdir(cp)) {
				printf("%s: Directory\n", cp);
				break;
			} else if ((fbuf = Fopen(cp, "r")) == NULL) {
				warn("%s", cp);
				break;
			}
			printf("\"%s\" ", cp);
			(void)fflush(stdout);
			lc = 0;
			cc = 0;
			while ((rc = readline(fbuf, linebuf, LINESIZE)) >= 0) {
				if (rc != LINESIZE - 1)
					lc++;
				if ((t = putline(collf, linebuf,
					 rc != LINESIZE - 1)) < 0) {
					(void)Fclose(fbuf);
					goto err;
				}
				cc += t;
			}
			(void)Fclose(fbuf);
			printf("%d/%d\n", lc, cc);
			break;
		case 'w':
			/*
			 * Write the message on a file.
			 */
			cp = &linebuf[2];
			while (*cp == ' ' || *cp == '\t')
				cp++;
			if (*cp == '\0') {
				fprintf(stderr, "Write what file!?\n");
				break;
			}
			if ((cp = expand(cp)) == NULL)
				break;
			rewind(collf);
			exwrite(cp, collf, 1);
			break;
		case 'm':
		case 'M':
		case 'f':
		case 'F':
			/*
			 * Interpolate the named messages, if we
			 * are in receiving mail mode.  Does the
			 * standard list processing garbage.
			 * If ~f is given, we don't shift over.
			 */
			if (forward(linebuf + 2, collf, tempname, c) < 0)
				goto err;
			goto cont;
		case '?':
			if ((fbuf = Fopen(_PATH_TILDE, "r")) == NULL) {
				warn("%s", _PATH_TILDE);
				break;
			}
			while ((t = getc(fbuf)) != EOF)
				(void)putchar(t);
			(void)Fclose(fbuf);
			break;
		case 'p':
			/*
			 * Print out the current state of the
			 * message without altering anything.
			 */
			rewind(collf);
			printf("-------\nMessage contains:\n");
			puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
			while ((t = getc(collf)) != EOF)
				(void)putchar(t);
			goto cont;
		case '|':
			/*
			 * Pipe message through command.
			 * Collect output as new message.
			 */
			rewind(collf);
			mespipe(collf, &linebuf[2]);
			goto cont;
		case 'v':
		case 'e':
			/*
			 * Edit the current message.
			 * 'e' means to use EDITOR
			 * 'v' means to use VISUAL
			 */
			rewind(collf);
			mesedit(collf, c);
			goto cont;
		}
	}
	goto out;
err:
	if (collf != NULL) {
		(void)Fclose(collf);
		collf = NULL;
	}
out:
	if (collf != NULL)
		rewind(collf);
	noreset--;
	(void)sigprocmask(SIG_BLOCK, &nset, NULL);
	(void)signal(SIGINT, saveint);
	(void)signal(SIGHUP, savehup);
	(void)signal(SIGTSTP, savetstp);
	(void)signal(SIGTTOU, savettou);
	(void)signal(SIGTTIN, savettin);
	(void)sigprocmask(SIG_UNBLOCK, &nset, NULL);
	return (collf);
}
示例#22
0
/*
 * Terminate an editing session by attempting to write out the user's
 * file from the temporary.  Save any new stuff appended to the file.
 */
static void
edstop(void)
{
    int gotcha, c;
    struct message *mp;
    FILE *obuf, *ibuf, *readstat;
    struct stat statb;
    char tempname[PATHSIZE];

    if (readonly)
        return;
    holdsigs();
    if (Tflag != NULL) {
        if ((readstat = Fopen(Tflag, "w")) == NULL)
            Tflag = NULL;
    }
    for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
        if (mp->m_flag & MNEW) {
            mp->m_flag &= ~MNEW;
            mp->m_flag |= MSTATUS;
        }
        if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
            gotcha++;
        if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
            char *id;

            if ((id = hfield("article-id", mp)) != NULL)
                fprintf(readstat, "%s\n", id);
        }
    }
    if (Tflag != NULL)
        Fclose(readstat);
    if (!gotcha || Tflag != NULL)
        goto done;
    ibuf = NULL;
    if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
        int fd;

        snprintf(tempname, sizeof(tempname), "%s/mbox.XXXXXXXXXX",
                 tmpdir);
        if ((fd = mkstemp(tempname)) == -1 ||
                (obuf = Fdopen(fd, "w")) == NULL) {
            warn("%s", tempname);
            relsesigs();
            reset(0);
        }
        if ((ibuf = Fopen(mailname, "r")) == NULL) {
            warn("%s", mailname);
            Fclose(obuf);
            rm(tempname);
            relsesigs();
            reset(0);
        }
        fseeko(ibuf, mailsize, SEEK_SET);
        while ((c = getc(ibuf)) != EOF)
            putc(c, obuf);
        Fclose(ibuf);
        Fclose(obuf);
        if ((ibuf = Fopen(tempname, "r")) == NULL) {
            warn("%s", tempname);
            rm(tempname);
            relsesigs();
            reset(0);
        }
        rm(tempname);
    }
    printf("\"%s\" ", mailname);
    fflush(stdout);
    if ((obuf = Fopen(mailname, "r+")) == NULL) {
        warn("%s", mailname);
        relsesigs();
        reset(0);
    }
    trunc(obuf);
    c = 0;
    for (mp = &message[0]; mp < &message[msgCount]; mp++) {
        if ((mp->m_flag & MDELETED) != 0)
            continue;
        c++;
        if (sendmessage(mp, obuf, NULL, NULL) < 0) {
            warnx("%s", mailname);
            relsesigs();
            reset(0);
        }
    }
    gotcha = (c == 0 && ibuf == NULL);
    if (ibuf != NULL) {
        while ((c = getc(ibuf)) != EOF)
            putc(c, obuf);
        Fclose(ibuf);
    }
    fflush(obuf);
    if (ferror(obuf)) {
        warn("%s", mailname);
        relsesigs();
        reset(0);
    }
    Fclose(obuf);
    if (gotcha) {
        rm(mailname);
        printf("removed\n");
    } else
        printf("complete\n");
    fflush(stdout);

done:
    relsesigs();
}
示例#23
0
文件: fio.c 项目: coyizumi/cs111
/*
 * Set up the input pointers while copying the mail file into /tmp.
 */
void
setptr(FILE *ibuf, off_t offset)
{
	int c, count;
	char *cp, *cp2;
	struct message this;
	FILE *mestmp;
	int maybe, inhead;
	char linebuf[LINESIZE], pathbuf[PATHSIZE];
	int omsgCount;

	/* Get temporary file. */
	(void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir);
	if ((c = mkstemp(pathbuf)) == -1 || (mestmp = Fdopen(c, "r+")) == NULL)
		err(1, "can't open %s", pathbuf);
	(void)rm(pathbuf);

	if (offset == 0) {
		 msgCount = 0;
	} else {
		/* Seek into the file to get to the new messages */
		(void)fseeko(ibuf, offset, SEEK_SET);
		/*
		 * We need to make "offset" a pointer to the end of
		 * the temp file that has the copy of the mail file.
		 * If any messages have been edited, this will be
		 * different from the offset into the mail file.
		 */
		(void)fseeko(otf, (off_t)0, SEEK_END);
		offset = ftello(otf);
	}
	omsgCount = msgCount;
	maybe = 1;
	inhead = 0;
	this.m_flag = MUSED|MNEW;
	this.m_size = 0;
	this.m_lines = 0;
	this.m_block = 0;
	this.m_offset = 0;
	for (;;) {
		if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) {
			if (append(&this, mestmp))
				errx(1, "temporary file");
			makemessage(mestmp, omsgCount);
			return;
		}
		count = strlen(linebuf);
		/*
		 * Transforms lines ending in <CR><LF> to just <LF>.
		 * This allows mail to be able to read Eudora mailboxes.
		 */
		if (count >= 2 && linebuf[count - 1] == '\n' &&
		    linebuf[count - 2] == '\r') {
			count--;
			linebuf[count - 1] = '\n';
		}

		(void)fwrite(linebuf, sizeof(*linebuf), count, otf);
		if (ferror(otf))
			errx(1, "/tmp");
		if (count)
			linebuf[count - 1] = '\0';
		if (maybe && linebuf[0] == 'F' && ishead(linebuf)) {
			msgCount++;
			if (append(&this, mestmp))
				errx(1, "temporary file");
			this.m_flag = MUSED|MNEW;
			this.m_size = 0;
			this.m_lines = 0;
			this.m_block = blockof(offset);
			this.m_offset = boffsetof(offset);
			inhead = 1;
		} else if (linebuf[0] == 0) {
			inhead = 0;
		} else if (inhead) {
			for (cp = linebuf, cp2 = "status";; cp++) {
				if ((c = *cp2++) == '\0') {
					while (isspace((unsigned char)*cp++))
						;
					if (cp[-1] != ':')
						break;
					while ((c = *cp++) != '\0')
						if (c == 'R')
							this.m_flag |= MREAD;
						else if (c == 'O')
							this.m_flag &= ~MNEW;
					inhead = 0;
					break;
				}
				if (*cp != c && *cp != toupper((unsigned char)c))
					break;
			}
		}
		offset += count;
		this.m_size += count;
		this.m_lines++;
		maybe = linebuf[0] == 0;
	}
}
示例#24
0
int main(){
  int clientfd = open_clientfd("elnux1.cs.umass.edu",48579);
  if(clientfd < 0){
    printf("%s\n", "connection error");
  }
  else{
    printf("%s\n","connected");

    FILE* file = Fdopen(clientfd,"a+");
    //send spire id
    printf("%s\n", "Sending Spire ID...." );
    fprintf(file, "28530995");
    //get question
    char* line = NULL;
    int count;
    getline(&line,&count,file);
    //print out question: the question is IDX
    printf("%s", "the question is");
    printf("%s\n", line);
    //get str and idx
    char *str;
    int idx;
    count= sscanf(line, "IDX%ms%d", &str, &idx);
    if(count == EOF){
      printf("%s\n", "sscanf error");
    }
    //calculate the answer
    char result = IDX(str,idx);
    //finish using str and line, free str and line
    free(str);
    free(line);
    line = NULL;

    //write the answer to server
    printf("sending answer: %c\n", result);
    fprintf(file, "%c\n", result);
    //receive msg from server, get line again
    getline(&line,&count,file);
    //print out msg
    printf("%s\n", line);
    //free the line and set line to NULL
    free(line);
    line=NULL;

    //write bonus to server
    fprintf(file, "%s\n", "HW9");

    //get bonus result
    getline(&line,&count,file);
    printf("%s\n", "The result is ");
    printf("%s\n", line);
    //free line and set it to NULL
    free(line);
    line = NULL;

    //close  file and clientfd
    Fclose(file);
    close(clientfd);
    printf("%s\n", "disconnect from server");
  }

}