+ char *tmpfilenam, *folder;
+
+ /* Store content in temporary file for now */
+ tmpfilenam = m_mktemp(invo_name, NULL, NULL);
+ ct->c_storage = getcpy(tmpfilenam);
+
+ /* Get the folder name */
+ if (cp[1])
+ folder = getcpy(expandfol(cp));
+ else
+ folder = getcurfol();
+
+ /* Check if folder exists */
+ create_folder(toabsdir(folder), 0, exit);
+
+ /* Record the folder name */
+ ct->c_folder = getcpy(folder);
+
+ if (cp[1])
+ free(folder);
+
+ goto got_filename;
+ }
+
+ /*
+ ** Parse and expand the storage formatting string
+ ** in `cp' into `buffer'.
+ */
+ parse_format_string(ct, cp, buffer, sizeof(buffer), dir);
+
+ /*
+ ** If formatting begins with '|' or '!', then pass
+ ** content to standard input of a command and return.
+ */
+ if (buffer[0] == '|' || buffer[0] == '!')
+ return show_content_aux(ct, 1, 0, buffer + 1, dir);
+
+ /* record the filename */
+ ct->c_storage = getcpy(buffer);
+
+got_filename:
+ /* flush the output stream */
+ fflush(stdout);
+
+ /* Now save or append the content to a file */
+ if (output_content_file(ct, appending) == NOTOK)
+ return NOTOK;
+
+ /*
+ ** If necessary, link the file into a folder and remove
+ ** the temporary file. If this message is a partial,
+ ** then only do this if it is the last one in the group.
+ */
+ if (ct->c_folder && (!is_partial || last_partial)) {
+ msgnum = output_content_folder(ct->c_folder, ct->c_storage);
+ unlink(ct->c_storage);
+ if (msgnum == NOTOK)
+ return NOTOK;
+ }
+
+ /*
+ ** Now print out the name/number of the message
+ ** that we are storing.
+ */
+ if (is_partial) {
+ if (first_partial)
+ fprintf(stderr, "reassembling partials ");
+ if (last_partial)
+ fprintf(stderr, "%s", ct->c_file);
+ else
+ fprintf(stderr, "%s,", ct->c_file);
+ } else {
+ fprintf(stderr, "storing message %s", ct->c_file);
+ if (ct->c_partno)
+ fprintf(stderr, " part %s", ct->c_partno);
+ }
+
+ /*
+ ** Unless we are in the "middle" of group of message/partials,
+ ** we now print the name of the file, folder, and/or message
+ ** to which we are storing the content.
+ */
+ if (!is_partial || last_partial) {
+ if (ct->c_folder) {
+ fprintf(stderr, " to folder %s as message %d\n",
+ ct->c_folder, msgnum);
+ } else if (strcmp(ct->c_storage, "-")==0) {
+ fprintf(stderr, " to stdout\n");
+ } else {
+ int cwdlen;
+
+ cwdlen = strlen(cwd);
+ fprintf(stderr, " as file %s\n",
+ strncmp(ct->c_storage, cwd,
+ cwdlen)!=0 ||
+ ct->c_storage[cwdlen] != '/' ?
+ ct->c_storage :
+ ct->c_storage + cwdlen + 1);
+ }
+ }
+
+ return OK;
+}
+
+
+/*
+** Output content to a file
+*/
+
+static int
+output_content_file(CT ct, int appending)
+{
+ int filterstate;
+ char *file, buffer[BUFSIZ];
+ long pos, last;
+ FILE *fp;
+
+ /*
+ ** If the pathname is absolute, make sure
+ ** all the relevant directories exist.
+ */
+ if (strchr(ct->c_storage, '/') && make_intermediates(ct->c_storage)
+ == NOTOK)
+ return NOTOK;
+
+ if (ct->c_encoding != CE_7BIT) {
+ int cc, fd;
+
+ if (!ct->c_ceopenfnx) {
+ advise(NULL, "don't know how to decode part %s of message %s", ct->c_partno, ct->c_file);
+ return NOTOK;
+ }
+
+ file = appending || strcmp(ct->c_storage, "-")==0 ?
+ NULL : ct->c_storage;
+ if ((fd = (*ct->c_ceopenfnx) (ct, &file)) == NOTOK)
+ return NOTOK;
+ if (strcmp(file, ct->c_storage)==0) {
+ (*ct->c_ceclosefnx) (ct);
+ return OK;
+ }
+
+ /*
+ ** Send to standard output
+ */
+ if (strcmp(ct->c_storage, "-")==0) {
+ int gd;
+
+ if ((gd = dup(fileno(stdout))) == NOTOK) {
+ advise("stdout", "unable to dup");
+losing:
+ (*ct->c_ceclosefnx) (ct);
+ return NOTOK;
+ }
+ if ((fp = fdopen(gd, appending ? "a" : "w")) == NULL) {
+ advise("stdout", "unable to fdopen (%d, \"%s\") from", gd, appending ? "a" : "w");
+ close(gd);
+ goto losing;
+ }
+ } else {
+ /*
+ ** Open output file
+ */
+ if ((fp = fopen(ct->c_storage, appending ? "a" : "w"))
+ == NULL) {
+ advise(ct->c_storage, "unable to fopen for %s",
+ appending ?
+ "appending" : "writing");
+ goto losing;
+ }
+ }
+
+ /*
+ ** Filter the header fields of the initial enclosing
+ ** message/partial into the file.
+ */
+ if (ct->c_type == CT_MESSAGE && ct->c_subtype == MESSAGE_PARTIAL) {
+ struct partial *pm = (struct partial *) ct->c_ctparams;
+
+ if (pm->pm_partno == 1)
+ copy_some_headers(fp, ct);
+ }
+
+ for (;;) {
+ switch (cc = read(fd, buffer, sizeof(buffer))) {
+ case NOTOK:
+ advise(file, "error reading content from");
+ break;
+
+ case OK:
+ break;
+
+ default:
+ fwrite(buffer, sizeof(*buffer), cc, fp);
+ continue;
+ }
+ break;
+ }
+
+ (*ct->c_ceclosefnx) (ct);
+
+ if (cc != NOTOK && fflush(fp))
+ advise(ct->c_storage, "error writing to");
+
+ fclose(fp);
+
+ return (cc != NOTOK ? OK : NOTOK);
+ }
+
+ if (!ct->c_fp && (ct->c_fp = fopen(ct->c_file, "r")) == NULL) {
+ advise(ct->c_file, "unable to open for reading");
+ return NOTOK;
+ }
+
+ pos = ct->c_begin;
+ last = ct->c_end;
+ fseek(ct->c_fp, pos, SEEK_SET);
+
+ if (strcmp(ct->c_storage, "-")==0) {
+ int gd;
+
+ if ((gd = dup(fileno(stdout))) == NOTOK) {
+ advise("stdout", "unable to dup");
+ return NOTOK;
+ }
+ if ((fp = fdopen(gd, appending ? "a" : "w")) == NULL) {
+ advise("stdout", "unable to fdopen (%d, \"%s\") from",
+ gd, appending ? "a" : "w");
+ close(gd);
+ return NOTOK;
+ }