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); }
/** * @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; }
/** * @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; }
/** * @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; }
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; }
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; }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
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; }
/* * @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; }
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; }
/* * 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); }
/* * 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; } }
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); }
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; }
/* * 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); }
/* * 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; }
/* * @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; }
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); }
/* * 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(); }
/* * 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; } }
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"); } }