+ case CDCMDSW:
+ /* Change the working directory for attachments
+ *
+ * Run the directory through the user's shell so that
+ * we can take advantage of any syntax that the user
+ * is accustomed to. Read back the absolute path.
+ */
+
+ if (*(argp+1) == NULL) {
+ strcpy(buf, "$SHELL -c \"cd&&pwd\"");
+ }
+ else {
+ writesomecmd(buf, BUFSIZ, "cd", "pwd", argp);
+ }
+ if ((f = popen_in_dir(cwd, buf, "r")) != NULL) {
+ if (fgets(cwd, sizeof (cwd), f) == NULL) {
+ advise (buf, "fgets");
+ }
+ trim_suffix_c(cwd, '\n');
+ pclose(f);
+ }
+ else {
+ advise("popen", "could not get directory");
+ }
+
+ break;
+
+ case PWDCMDSW:
+ /* Print the working directory for attachments */
+ puts(cwd);
+ break;
+
+ case LSCMDSW:
+ /* List files in the current attachment working directory
+ *
+ * Use the user's shell so that we can take advantage of any
+ * syntax that the user is accustomed to.
+ */
+ writelscmd(buf, sizeof(buf), "", argp);
+ (void)system_in_dir(cwd, buf);
+ break;
+
+ case ALISTCMDSW:
+ /*
+ * List attachments on current draft. Options are:
+ *
+ * -l long listing (full path names)
+ * -n numbers listing
+ */
+
+ if (checkmimeheader(drft))
+ break;
+
+ l = NULL;
+ n = 0;
+
+ while (*++argp != NULL) {
+ if (strcmp(*argp, "-l") == 0)
+ l = "/";
+
+ else if (strcmp(*argp, "-n") == 0)
+ n = 1;
+
+ else if (strcmp(*argp, "-ln") == 0 || strcmp(*argp, "-nl") == 0) {
+ l = "/";
+ n = 1;
+ }
+
+ else {
+ n = -1;
+ break;
+ }
+ }
+
+ if (n == -1)
+ inform("usage is alist [-ln].");
+
+ else
+ annolist(drft, ATTACH_FIELD, l, n);
+
+ break;
+
+ case ATTACHCMDSW: {
+ /*
+ * Attach files to current draft.
+ */
+
+ int verbose = 0;
+ char **ap;
+
+ if (checkmimeheader(drft))
+ break;
+
+ for (ap = argp+1; *ap; ++ap) {
+ if (strcmp(*ap, "-v") == 0) {
+ ++argp;
+ verbose = 1;
+ } else if (*ap[0] != '-') {
+ break;
+ }
+ }
+
+ if (*(argp+1) == NULL) {
+ inform("attach command requires file argument(s).");
+ break;
+ }
+
+ /*
+ * Build a command line that causes the user's shell to list the file name
+ * arguments. This handles and wildcard expansion, tilde expansion, etc.
+ */
+ writelscmd(buf, sizeof(buf), "-d --", argp);
+
+ /*
+ * Read back the response from the shell, which contains a number of lines
+ * with one file name per line. Remove off the newline. Determine whether
+ * we have an absolute or relative path name. Prepend the current working
+ * directory to relative path names. Add the attachment annotation to the
+ * draft.
+ */
+
+ if ((f = popen_in_dir(cwd, buf, "r")) != NULL) {
+ while (fgets(shell, sizeof (shell), f) != NULL) {
+ char *ctype;
+
+ trim_suffix_c(shell, '\n');
+
+ if (*shell == '/') {
+ strncpy(file, shell, sizeof(file));
+ file[sizeof(file) - 1] = '\0';
+ } else {
+ snprintf(file, sizeof(file), "%s/%s", cwd, shell);
+ }
+
+ annotate(drft, ATTACH_FIELD, file, 1, 0, -2, 1);
+ if (verbose) {
+ ctype = mime_type(file);
+ printf ("Attaching %s as a %s\n", file, ctype);
+ free (ctype);
+ }
+ }
+
+ pclose(f);
+ }
+ else {
+ advise("popen", "could not get file from shell");
+ }
+
+ break;
+ }
+ case DETACHCMDSW:
+ /*
+ * Detach files from current draft.
+ */
+
+ /*
+ * Scan the arguments for a -n. Mixed file names and numbers aren't allowed,
+ * so this catches a -n anywhere in the argument list.
+ */
+
+ if (checkmimeheader(drft))
+ break;
+
+ for (n = 0, arguments = argp + 1; *arguments != NULL; arguments++) {
+ if (strcmp(*arguments, "-n") == 0) {
+ n = 1;
+ break;
+ }
+ }
+
+ /*
+ * A -n was found so interpret the arguments as attachment numbers.
+ * Decrement any remaining argument number that is greater than the one
+ * just processed after processing each one so that the numbering stays
+ * correct.
+ */
+
+ if (n == 1) {
+ for (arguments = argp + 1; *arguments != NULL; arguments++) {
+ if (strcmp(*arguments, "-n") == 0)
+ continue;
+
+ if (**arguments != '\0') {
+ n = atoi(*arguments);
+ annotate(drft, ATTACH_FIELD, NULL, 1, 0, n, 1);
+
+ for (argp = arguments + 1; *argp != NULL; argp++) {
+ if (atoi(*argp) > n) {
+ if (atoi(*argp) == 1)
+ *argp = "";
+ else
+ (void)sprintf(*argp, "%d", atoi(*argp) - 1);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * The arguments are interpreted as file names. Run them through the
+ * user's shell for wildcard expansion and other goodies. Do this from
+ * the current working directory if the argument is not an absolute path
+ * name (does not begin with a /).
+ *
+ * We feed all the file names to the shell at once, otherwise you can't
+ * provide a file name with a space in it.
+ */
+ writelscmd(buf, sizeof(buf), "-d --", argp);
+ if ((f = popen_in_dir(cwd, buf, "r")) != NULL) {
+ while (fgets(shell, sizeof (shell), f) != NULL) {
+ trim_suffix_c(shell, '\n');
+ annotate(drft, ATTACH_FIELD, shell, 1, 0, 0, 1);
+ }
+ pclose(f);
+ } else {
+ advise("popen", "could not get file from shell");
+ }
+
+ break;
+
+ default: