2 Proprietary Rand Corporation
, 1981.
3 Further distribution of
this software
4 subject to the terms of the Rand
13 #include <sys/types.h>
15 #include "../adrparse.h"
17 #define ERRHOST "?????"
24 struct swit anyl
[] = {
31 struct swit aleqs
[] = {
33 "edit [<editor>]", 0, /* 1 */
34 "quit [delete]", 0, /* 2 */
35 "send [switches]", 0, /* 3 */
40 #define OUTPUTLINELEN 72
41 short outputlinelen
= OUTPUTLINELEN
;
45 short format
= -1; /* Default to re-format optionally*/
46 short inplace
; /* preserve links in anno */
50 struct swit switches
[] = {
51 "annotate", 0, /* 0 */
52 "noannotate", 0, /* 1 */
55 "editor editor", 0, /* 4 */
57 "noformat", 0, /* 6 */
59 "noinplace", 0, /* 8 */
77 char *folder
, *msg
, *maildir
;
78 register char *cp
, **ap
, **argp
;
85 msg
= 0; anot
= 0; folder
= 0;
87 cp
= r1bindex(argv
[0], '/');
88 if((cp
= m_find(cp
)) != NULL
) {
89 ap
= brkstring(cp
= getcpy(cp
), " ", "\n");
90 ap
= copyip(ap
, arguments
);
93 VOID
copyip(argv
+1, ap
);
97 switch(smatch(++cp
, switches
)) {
98 case -2:ambigsw(cp
, switches
); /* ambiguous */
101 case -1:fprintf(stderr
, "repl: -%s unknown\n", cp
);
103 case 0: anot
= 1; continue; /* -annotate */
104 case 1: anot
= 0; continue; /* -noannotate */
105 case 2: ccme
= 1; continue; /* -ccme */
106 case 3: ccme
= 0; continue; /* -noccme */
107 case 4: if(!(ed
= *argp
++)) { /* -editor */
108 missing
: fprintf(stderr
, "repl: Missing argument for %s switch\n", argp
[-2]);
112 case 5: format
= 1; continue; /* -format */
113 case 6: format
= 0; continue; /* -noformat */
114 case 7: inplace
= 1; continue; /* -inplace */
115 case 8: inplace
= 0; continue; /* -noinplace */
116 case 9: if(!(cp
= *argp
++) || *cp
== '-')
118 outputlinelen
= atoi(cp
); continue;
120 case 10:help("repl [+folder] [msg] [switches]",
123 case 11:debug
++; continue; /* -debug */
128 fprintf(stderr
, "Only one folder at a time.\n");
131 folder
= path(cp
+1, TFOLDER
);
133 fprintf(stderr
, "Only one message per reply.\n");
138 if(!m_find("path")) free(path("./", TFOLDER
));
142 folder
= m_getfolder();
143 maildir
= m_maildir(folder
);
144 if(chdir(maildir
) < 0) {
145 fprintf(stderr
, "Can't chdir to: ");
149 if(!(mp
= m_gmsg(folder
))) {
150 fprintf(stderr
, "Can't read folder!?\n");
153 if(mp
->hghmsg
== 0) {
154 fprintf(stderr
, "No messages in \"%s\".\n", folder
);
159 if(mp
->numsel
== 0) {
160 fprintf(stderr
, "repl: pepperoni pizza\n");/* never get here */
164 fprintf(stderr
, "Only one message at a time.\n");
167 m_replace(pfolder
, folder
);
168 if(mp
->lowsel
!= mp
->curmsg
)
169 m_setcur(mp
->lowsel
);
170 repl(getcpy(m_name(mp
->lowsel
)));
184 char name
[NAMESZ
], field
[BUFSIZ
];
185 char *drft
, *msgid
, *replto
, *from
, *sub
, *date
, *sender
, *to
, *cc
;
189 struct mailname
*mnp
= 0;
192 /***/if(debug
) printf("repl(%s)\n", msg
);
193 if((in
= fopen(msg
, "r")) == NULL
) {
194 fprintf(stderr
, "Can't open "); perror(msg
);
197 drft
= m_maildir(draft
);
198 /***/if(debug
) printf("drft=%s\n", drft
);
199 if(stat(drft
, &stbuf
) != -1) {
200 cp
= concat("\"", drft
, "\" exists; delete? ", 0);
201 while((i
= gans(cp
, anyl
)) == 2)
207 if((out
= fopen(drft
, "w")) == NULL
) {
208 fprintf(stderr
, "Can't create \"%s\".\n", drft
);
211 VOID
chmod(drft
, m_gmprot());
214 to
= cc
= sender
= replto
= msgid
= from
= sub
= date
= 0;
218 switch(state
= m_getfld(state
, name
, field
, sizeof field
, in
)) {
223 if(uleq(name
, "from")) {
224 if(state
== FLD
&& from
) from
= add(",",from
);
225 from
= add(field
, from
);
227 if(uleq(name
, "cc")) {
228 if(state
== FLD
&& cc
) cc
= add(",",cc
);
231 if(uleq(name
, "subject"))
232 sub
= add(field
, sub
);
233 if(uleq(name
, "date"))
234 date
= add(field
, date
);
235 if(uleq(name
, "to")) {
236 if(state
== FLD
&& to
) to
= add(",",to
);
239 if(uleq(name
, "message-id"))
240 msgid
= add(field
, msgid
);
241 if(uleq(name
, "reply-to")) {
242 if(state
== FLD
&& replto
) replto
= add(",",replto
);
243 replto
= add(field
, replto
);
245 if(uleq(name
, "sender")) {
246 if(state
== FLD
&& sender
) sender
= add(",",sender
);
247 sender
= add(field
, sender
);
259 fprintf(stderr
, "getfld returned %d\n", state
);
268 if(!(sender
|| from
)) {
269 fprintf(stderr
, "repl: No Sender or From!?\n");
273 /* Pick up replacement host from "sender", else "from" */
275 if((cp
= getname(sender
? sender
: from
)) == 0)
277 if((mnp
= getm(cp
, HOSTNAME
)) == 0)
280 if((mnp
-> m_at
) && ((*mnp
-> m_at
) == '!')) { /* UUCP address */
281 cp
= stdhost((long)HOSTNUM
);
284 cp
= stdhost(mnp
->m_hnum
);
286 fprintf(stderr
, "repl: Unknown host: %s\n", mnp
->m_host
);
293 mn_rep
= getcpy (HOSTNAME
);
295 while(getname("")) ; /* In case multi-name from/sender */
297 /***/if(debug
) printf("before testformats\n");
298 /* Set format flag to 0 or 1 based on actual addresses, */
299 /* provided it hasn't been explicitly set */
301 if(format
== -1 && *mn_rep
== '?') /* Oops, error in sender/from.*/
302 format
= 1; /* Format! Use replacement host ERRHOST */
303 if(format
== -1) testformat(sender
);
304 if(format
== -1) testformat(from
);
305 if(format
== -1) testformat(replto
);
306 if(format
== -1) testformat(to
);
307 if(format
== -1) testformat(cc
);
308 if(format
== -1) format
= 0; /* All LOCAL--don't format! */
310 /***/if(debug
) printf("after testformats\n");
311 if(!(from
|| replto
)) {
312 fprintf(stderr
, "No one to reply to!!!\n");
315 outfmt(out
, replto
? replto
: from
, "To", 0);
317 if(to
&& cc
) /* Combine to & cc data */
321 outfmt(out
, to
, "Cc", 1);
323 if(sub
) { /* Subject: Re: */
324 fprintf(out
, "Subject: ");
325 if(*sub
== ' ') sub
++;
326 if((sub
[0] != 'R' && sub
[0] != 'r') ||
327 (sub
[1] != 'E' && sub
[1] != 'e') ||
329 fprintf(out
, "Re: ");
332 if(date
) { /* In-reply-to: */
333 date
[strlen(date
)-1] = '.';
334 if(*date
== ' ') date
++;
335 fprintf(out
, "In-reply-to: Your message of %s\n", date
);
337 if(*msgid
== ' ') msgid
++;
338 fprintf(out
, " %s", msgid
);
341 fprintf(out
, "----------\n");
343 fprintf(out
, "\nREPL: CANT CONSTRUCT:\n%s\n", badaddrs
);
344 if(fclose(out
) == EOF
) {
345 fprintf(stderr
, "reply: Write error on ");
350 if(m_edit(&ed
, drft
, NOUSE
, msg
) < 0)
353 fprintf(stderr
, "!! Test Version of SEND Being Run !!\n");
354 fprintf(stderr
, " Send verbose !\n\n");
358 if(!(argp
= getans("\nWhat now? ", aleqs
))) {
362 switch(smatch(*argp
, aleqs
)) {
363 case 0: VOID
showfile(drft
); /* list */
366 case 1: if(*++argp
) /* edit */
368 if(m_edit(&ed
, drft
, NOUSE
, msg
) == -1)
372 case 2: if(*++argp
&& (*argp
[0] == 'd' || /* quit */
373 (*argp
[0]=='-' && *argp
[1]=='d')))
374 if(unlink(drft
) == -1) {
375 fprintf(stderr
, "Can't unlink %s ", drft
);
381 if(!mp
->msgflags
&READONLY
) { /* annotate first */
383 while((pid
= fork()) == -1) sleep(5);
385 while((wpid
=wait((int *)NULL
))!= -1
387 if(stat(drft
, &stbuf
) == -1)
388 annotate(msg
, "Replied", "", inplace
);
393 VOID
m_send(++argp
, drft
);
396 default:fprintf(stderr
, "repl: illegal option\n"); /*##*/
403 outfmt(out
, str
, fn
, chk
)
409 register struct mailname
*mnp
= 0;
410 short ccoutput
= 0, linepos
= 0, len
;
412 /***/if(debug
)printf("outfmt mn_rep=%s\n", mn_rep
);
413 while(cp
= getname(str
)) {
415 /***/if(debug
)printf("Parse '%s'\n",cp
);
417 /* If couldn't find foreign default host due to sender/from */
418 /* parse error, hand adrparse HOSTNAME for the time. */
420 if((mnp
= getm(cp
, *mn_rep
== '?' ? HOSTNAME
: mn_rep
)) == 0){
422 /* Can't parse. Add to badlist. */
423 VOID
sprintf(buf
, " %s: %s\n", fn
, cp
);
424 badaddrs
= add(buf
, badaddrs
);
426 } else if(*mn_rep
== '?') {
428 * Now must distinguish between explicit-local and
429 * hostless-foreign, which parse identically
430 * because of the borrowed HOSTNAME.
431 * Kludge: If same string gives parse error when
432 * default host is ERRHOST, then original string was
433 * hostless (foreign). Otherwise original string had
434 * HOSTNAME explicitly and is local.
436 struct mailname
*tmpmnp
;
438 if(tmpmnp
= getm(cp
, ERRHOST
))
441 mnp
->m_host
= getcpy(ERRHOST
);
444 /***/if(debug
) printf ("Host %D\n",mnp
->m_hnum
);
445 if(chk
&& !ccme
&& uleq(mnp
->m_mbox
, getenv("USER")) &&
446 mnp
->m_hnum
== HOSTNUM
)
449 fprintf(out
, "%s: ", fn
);
450 linepos
+= (ccoutput
= strlen(fn
) + 2);
452 if((format
&& *mn_rep
!= '?')|| ((mnp
->m_at
&& *mnp
->m_at
!= '!') &&
453 (mnp
->m_hnum
!= HOSTNUM
)) ) {
455 /***/if(debug
) printf ("That's not %d, so format it (name %s)\n",
457 cp
= adrformat(mnp
,HOSTNAME
);
458 /***/if(debug
) printf ("Formatting produces '%s'\n",cp
);
460 else if (format
&& *mn_rep
== '?') {
461 cp
= adrformat(mnp
, mn_rep
);
466 if(linepos
!= ccoutput
)
467 if(len
+ linepos
+ 2 > outputlinelen
) {
468 fprintf(out
, ",\n%*s", ccoutput
, "");
478 if(linepos
) putc('\n', out
);
485 register struct mailname
*mnp
;
489 while(cp
= getname(str
)) {
490 if(mnp
= getm(cp
, mn_rep
)) {
491 if((mnp
->m_hnum
!= HOSTNUM
) &&
492 (mnp
->m_at
) && (*mnp
->m_at
!= '!'))