* pwd command and exists to allow the user
* to verify the directory.
*
- * attach files This option attaches the named files to
- * the draft.
+ * attach [-v [-a 0|1|2]] files
+ * This option attaches the named files to
+ * the draft. -v displays the mhbuild
+ * directive, using the optionally specified
+ * attachformat [-a] if that is also provided
+ * to send(1).
*
* alist [-ln] This option lists the attachments on the
* draft. -l gets long listings, -n gets
#include <h/mh.h>
#include <fcntl.h>
-#include <signal.h>
#include <h/mime.h>
#include <h/utils.h>
X("cd [directory]", 0, CDCMDSW) \
X("pwd", 0, PWDCMDSW) \
X("ls", 2, LSCMDSW) \
- X("attach", 0, ATTACHCMDSW) \
- X("detach [-n]", 2, DETACHCMDSW) \
+ X("attach [-v [-a 0|1|2]]", 0, ATTACHCMDSW) \
+ X("detach [-n]", 0, DETACHCMDSW) \
X("alist [-ln] ", 2, ALISTCMDSW) \
#define X(sw, minchars, id) id,
static void writesomecmd(char *buf, int bufsz, char *cmd, char *trailcmd, char **argp);
static FILE* popen_in_dir(const char *dir, const char *cmd, const char *type);
static int system_in_dir(const char *dir, const char *cmd);
-
-
-#ifdef HAVE_LSTAT
static int copyf (char *, char *);
-#endif
int
break;
- case ATTACHCMDSW:
+ case ATTACHCMDSW: {
/*
* Attach files to current draft.
*/
+ int verbose = 0;
+ int attachformat = 1;
+ char **ap;
+
if (attach == (char *)0) {
advise((char *)0, "can't attach because no header field name was given.");
break;
}
+ for (ap = argp+1; *ap; ++ap) {
+ if (strcmp(*ap, "-v") == 0) {
+ ++argp;
+ verbose = 1;
+ } else if (strcmp(*ap, "-a") == 0) {
+ ++argp;
+ if (*(ap+1) == NULL ||
+ ! isdigit ((unsigned char) *(ap+1)[0])) {
+ advise(NULL,
+ "ignoring attach -a without format argument.");
+ } else {
+ ++argp;
+ ++ap;
+ if ((attachformat = atoi(*ap)) > 2) {
+ advise(NULL,
+ "ignoring invalid attachformat value of %d",
+ attachformat);
+ attachformat = 1;
+ }
+ }
+ } else if (*ap[0] != '-') {
+ break;
+ }
+ }
+
if (*(argp+1) == (char *)0) {
- advise((char *)0, "attach command requires file argument(s).");
+ advise(NULL, "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);
+ writelscmd(buf, sizeof(buf), "-d --", argp);
/*
* Read back the response from the shell, which contains a number of lines
if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) {
while (fgets(shell, sizeof (shell), f) != (char *)0) {
+ char *build_directive;
+
*(strchr(shell, '\n')) = '\0';
- if (*shell == '/')
+ if (*shell == '/') {
(void)annotate(drft, attach, shell, 1, 0, -2, 1);
- else {
+ if (verbose) {
+ build_directive =
+ construct_build_directive (shell, NULL,
+ attachformat);
+ }
+ } else {
(void)sprintf(file, "%s/%s", cwd, shell);
(void)annotate(drft, attach, file, 1, 0, -2, 1);
+ if (verbose) {
+ build_directive =
+ construct_build_directive (file, NULL,
+ attachformat);
+ }
+ }
+
+ if (verbose) {
+ printf ("%s", build_directive);
+ free (build_directive);
}
}
}
break;
-
+ }
case DETACHCMDSW:
/*
* Detach files from current draft.
* 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);
+ writelscmd(buf, sizeof(buf), "-d --", argp);
if ((f = popen_in_dir(cwd, buf, "r")) != (FILE *)0) {
while (fgets(shell, sizeof (shell), f) != (char *)0) {
*(strchr(shell, '\n')) = '\0';
int trailln = strlen(trailcmd) + 4;
if (ln < 0 || ln + trailln > bufsz)
adios((char *)0, "arguments too long");
-
+
cp = buf + ln;
-
- while (*++argp != (char *)0) {
+
+ while (*argp && *++argp) {
ln = strlen(*argp);
/* +1 for leading space */
if (ln + trailln + 1 > bufsz - (cp-buf))
static void
writelscmd(char *buf, int bufsz, char *lsoptions, char **argp)
{
- char *lscmd = concat ("ls ", lsoptions, " --", NULL);
+ char *lscmd = concat ("ls ", lsoptions, NULL);
writesomecmd(buf, bufsz, lscmd, "", argp);
free (lscmd);
}
/* ensure that $SHELL exists, as the cmd was written relying on
a non-blank $SHELL... */
setenv("SHELL","/bin/sh",0); /* don't overwrite */
-
+
if (getcwd(olddir, sizeof(olddir)) == 0)
adios("getcwd", "could not get working directory");
if (chdir(dir) != 0)
char *cp, *prog, **vec;
struct stat st;
-#ifdef HAVE_LSTAT
int slinked = 0;
-#endif /* HAVE_LSTAT */
/* Was there a previous edit session? */
if (reedit) {
if (atfile) {
unlink (linkpath);
-#ifdef HAVE_LSTAT
if (link (altpath, linkpath) == NOTOK) {
symlink (altpath, linkpath);
slinked = 1;
} else {
slinked = 0;
}
-#else /* not HAVE_LSTAT */
- link (altpath, linkpath);
-#endif /* not HAVE_LSTAT */
}
}
context_save (); /* save the context file */
fflush (stdout);
- switch (pid = vfork()) {
+ switch (pid = fork()) {
case NOTOK:
advise ("fork", "unable to");
status = NOTOK;
}
reedit++;
-#ifdef HAVE_LSTAT
if (altmsg
&& mp
&& !is_readonly(mp)
&& (unlink (altpath) == NOTOK
|| link (linkpath, altpath) == NOTOK)))
advise (linkpath, "unable to update %s from", altmsg);
-#else /* HAVE_LSTAT */
- if (altmsg
- && mp
- && !is_readonly(mp)
- && stat (linkpath, &st) != NOTOK
- && st.st_nlink == 1
- && (unlink (altpath) == NOTOK
- || link (linkpath, altpath) == NOTOK))
- advise (linkpath, "unable to update %s from", altmsg);
-#endif /* HAVE_LSTAT */
}
/* normally, we remember which editor we used */
}
-#ifdef HAVE_LSTAT
static int
copyf (char *ifile, char *ofile)
{
close (out);
return i;
}
-#endif /* HAVE_LSTAT */
/*
{
pid_t child_id;
int i, vecp;
- char *cp, *sp, *vec[MAXARGS];
+ char *cp, *sp, **vec, *program;
/* Translate MIME composition file, if necessary */
if ((cp = context_find ("automimeproc"))
context_save (); /* save the context file */
fflush (stdout);
- for (i = 0; (child_id = vfork()) == NOTOK && i < 5; i++)
+ for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
sleep (5);
switch (child_id) {
case NOTOK:
advise (NULL, "unable to fork, so sending directly...");
case OK:
- vecp = 0;
- vec[vecp++] = invo_name;
+ vec = argsplit(sendproc, &program, &vecp);
if (pushsw)
vec[vecp++] = "-push";
if (arg)
vec[vecp++] = file;
vec[vecp] = NULL;
- execvp (sendproc, vec);
+ execvp (program, vec);
fprintf (stderr, "unable to exec ");
perror (sendproc);
_exit (-1);
*/
if (uprf (name, XXX_FIELD_PRF)) {
fclose (fp);
+ m_getfld_state_destroy (&gstate);
return 0;
}
while (state == FLDPLUS) {
for (bp = buf; *bp; bp++)
if (*bp != ' ' && *bp != '\t' && *bp != '\n') {
fclose (fp);
+ m_getfld_state_destroy (&gstate);
return 1;
}
default:
fclose (fp);
+ m_getfld_state_destroy (&gstate);
return 0;
}
}
- m_getfld_state_destroy (&gstate);
}
X("help", 0, SHELPSW) \
X("dashstuffing", -12, BITSTUFFSW) \
X("nodashstuffing", -14, NBITSTUFFSW) \
- X("mail", -4, MAILSW) \
- X("saml", -4, SAMLSW) \
- X("send", -4, SSNDSW) \
- X("soml", -4, SOMLSW) \
X("client host", -6, CLIESW) \
X("server host", 6, SERVSW) \
X("snoop", -5, SNOOPSW) \
X("saslmaxssf", SASLminc(-10), SASLMXSSFSW) \
X("saslmech", SASLminc(-5), SASLMECHSW) \
X("user", SASLminc(-4), USERSW) \
- X("attach file", 6, SNDATTACHSW) \
+ X("attach fieldname", 6, SNDATTACHSW) \
X("noattach", 0, SNDNOATTACHSW) \
X("attachformat", 7, SNDATTACHFORMAT) \
X("port server-port-name/number", 4, PORTSW) \
X("tls", TLSminc(-3), TLSSW) \
+ X("initialtls", TLSminc(-10), INITTLSSW) \
X("notls", TLSminc(-5), NTLSSW) \
X("mts smtp|sendmail/smtp|sendmail/pipe", 2, MTSSW) \
X("messageid localname|random", 2, MESSAGEIDSW) \
sendit (char *sp, char **arg, char *file, int pushed)
{
int vecp, n = 1;
- char *cp, buf[BUFSIZ], **argp;
- char **arguments, *vec[MAXARGS];
+ char *cp, buf[BUFSIZ], **argp, *program;
+ char **arguments, *savearg[MAXARGS], **vec;
struct stat st;
char *attach = NMH_ATTACH_HEADER;/* attachment header field name */
int attachformat = 1; /* mhbuild format specifier for
/*
* Make sure these are defined. In particular, we need
- * vec[1] to be NULL, in case "arg" is NULL below. It
- * doesn't matter what is the value of vec[0], but we
+ * savearg[1] to be NULL, in case "arg" is NULL below. It
+ * doesn't matter what is the value of savearg[0], but we
* set it to NULL, to help catch "off-by-one" errors.
*/
- vec[0] = NULL;
- vec[1] = NULL;
+ savearg[0] = NULL;
+ savearg[1] = NULL;
/*
- * Temporarily copy arg to vec, since the brkstring() call in
+ * Temporarily copy arg to savearg, since the brkstring() call in
* getarguments() will wipe it out before it is merged in.
- * Also, we skip the first element of vec, since getarguments()
+ * Also, we skip the first element of savearg, since getarguments()
* skips it. Then we count the number of arguments
* copied. The value of "n" will be one greater than
* this in order to simulate the standard argc/argv.
if (arg) {
char **bp;
- copyip (arg, vec+1, MAXARGS-1);
- bp = vec+1;
+ copyip (arg, savearg+1, MAXARGS-1);
+ bp = savearg+1;
while (*bp++)
n++;
}
/*
- * Merge any arguments from command line (now in vec)
+ * Merge any arguments from command line (now in savearg)
* and arguments from profile.
*/
- arguments = getarguments (sp, n, vec, 1);
+ arguments = getarguments (sp, n, savearg, 1);
argp = arguments;
debugsw = 0;
annotext = NULL;
distfile = NULL;
- vecp = 1; /* we'll get the zero'th element later */
+ /*
+ * Get our initial arguments for postproc now
+ */
+
+ vec = argsplit(postproc, &program, &vecp);
+
vec[vecp++] = "-library";
vec[vecp++] = getcpy (m_maildir (""));
if ((cp = context_find ("fileproc"))) {
- vec[vecp++] = "-fileproc";
- vec[vecp++] = cp;
+ vec[vecp++] = "-fileproc";
+ vec[vecp++] = cp;
}
if ((cp = context_find ("mhlproc"))) {
- vec[vecp++] = "-mhlproc";
- vec[vecp++] = cp;
+ vec[vecp++] = "-mhlproc";
+ vec[vecp++] = cp;
+ }
+
+ if ((cp = context_find ("credentials"))) {
+ /* post doesn't read context so need to pass credentials. */
+ vec[vecp++] = "-credentials";
+ vec[vecp++] = cp;
}
while ((cp = *argp++)) {
case NMSGDSW:
case WATCSW:
case NWATCSW:
- case MAILSW:
- case SAMLSW:
- case SSNDSW:
- case SOMLSW:
case SNOOPSW:
case SASLSW:
case NOSASLSW:
case TLSSW:
+ case INITTLSSW:
case NTLSSW:
vec[vecp++] = --cp;
continue;
if ((pushsw = pushed))
push ();
- vec[0] = r1bindex (postproc, '/');
closefds (3);
- if (sendsbr (vec, vecp, file, &st, 1, attach, attachformat) == OK)
+ if (sendsbr (vec, vecp, program, file, &st, 1, attach, attachformat) == OK)
done (0);
}
{
pid_t pid;
int vecp;
- char *vec[MAXARGS];
+ char **vec, *program;
context_save (); /* save the context file */
fflush (stdout);
- switch (pid = vfork()) {
+ switch (pid = fork()) {
case NOTOK:
advise ("fork", "unable to");
return 1;
case OK:
- vecp = 0;
- vec[vecp++] = r1bindex (whomproc, '/');
+ vec = argsplit(whomproc, &program, &vecp);
vec[vecp++] = file;
if (arg)
while (*arg)
vec[vecp++] = *arg++;
vec[vecp] = NULL;
- execvp (whomproc, vec);
+ execvp (program, vec);
fprintf (stderr, "unable to exec ");
perror (whomproc);
_exit (-1); /* NOTREACHED */