1 /* popi.c - POP initiator - for MPOP */
3 static char ident[] = "@(#)$Id: popi.c,v 1.8 1992/10/28 18:52:45 jromine Exp $";
7 #include "../h/formatsbr.h"
8 #include "../h/scansbr.h"
11 #include <sys/types.h>
13 #include "../h/local.h"
17 #include "../zotnet/mts.h"
22 #define RPOPminc(a) (a)
28 #define APOPminc(a) (a)
34 #define BPOPminc(a) (a)
40 #define BULKminc(a) (a)
45 static struct swit switches[] = {
47 "apop", APOPminc (-4),
49 "noapop", APOPminc (-6),
54 "noauto", BPOPminc(-6),
57 "bulk directory", BULKminc(-4),
72 "rpop", RPOPminc (-4),
74 "norpop", RPOPminc (-6),
90 static char *bulksw = NULLCP;
94 static char mailname[BUFSIZ];
96 static char *nfs = NULL;
98 static struct msgs *mp;
102 extern char response[];
129 invo_name = r1bindex (argv[0], '/');
130 mts_init (invo_name);
131 if (pophost && *pophost)
133 if ((cp = getenv ("MHPOPDEBUG")) && *cp)
135 if ((cp = m_find (invo_name)) != NULL) {
136 ap = brkstring (cp = getcpy (cp), " ", "\n");
137 ap = copyip (ap, arguments);
141 (void) copyip (argv + 1, ap);
144 rpop = getuid () && !geteuid ();
148 while (cp = *argp++) {
150 switch (smatch (++cp, switches)) {
152 ambigsw (cp, switches);
155 adios (NULLCP, "-%s unknown", cp);
157 (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
158 help (buf, switches);
169 if (!(bulksw = *argp++) || *bulksw == '-')
170 adios (NULLCP, "missing argument to %s", argp[-2]);
174 if (!(form = *argp++) || *form == '-')
175 adios (NULLCP, "missing argument to %s", argp[-2]);
179 if (!(format = *argp++) || *format == '-')
180 adios (NULLCP, "missing argument to %s", argp[-2]);
185 if (!(cp = *argp++) || *cp == '-')
186 adios (NULLCP, "missing argument to %s", argp[-2]);
191 if (!(host = *argp++) || *host == '-')
192 adios (NULLCP, "missing argument to %s", argp[-2]);
195 if (!(user = *argp++) || *user == '-')
196 adios (NULLCP, "missing argument to %s", argp[-2]);
211 if (!(mshproc = *argp++) || *mshproc == '-')
212 adios (NULLCP, "missing argument to %s", argp[-2]);
215 if (*cp == '+' || *cp == '@') {
217 adios (NULLCP, "only one folder at a time!");
219 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
222 adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
228 adios (NULLCP, "usage: %s -host \"host\"", invo_name);
240 (void) setuid (getuid ());
241 ruserpass (host, &user, &pass);
243 (void) sprintf (mailname, "PO box for %s@%s", user, host);
245 if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
246 adios (NULLCP, "%s", response);
248 (void) setuid (getuid ());
250 nfs = new_fs (form, format, FORMAT);
252 if (!m_find ("path"))
253 free (path ("./", TFOLDER));
254 if (!folder && !(folder = m_find (inbox)))
256 maildir = m_maildir (folder);
258 if (stat (maildir, &st) == NOTOK) {
260 adios (maildir, "error on folder");
261 cp = concat ("Create folder \"", maildir, "\"? ", NULLCP);
262 if (noisy && !getanswer (cp))
265 if (!makedir (maildir))
266 adios (NULLCP, "unable to create folder %s", maildir);
269 if (chdir (maildir) == NOTOK)
270 adios (maildir, "unable to change directory to");
271 if (!(mp = m_gmsg (folder)))
272 adios (NULLCP, "unable to read folder %s", folder);
283 m_replace (pfolder, folder);
295 static struct swit popicmds[] = {
339 printf ("(%s) ", invo_name);
340 for (cp = buffer; (i = getchar ()) != '\n'; ) {
342 (void) putchar ('\n');
349 if (cp < buffer + sizeof buffer - 2)
353 if (buffer[0] == '\0')
355 if (buffer[0] == '?') {
356 printf ("commands:\n");
357 printsw (ALL, popicmds, "");
358 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name);
362 if (cp = index (buffer, ' '))
364 switch (i = smatch (buffer, popicmds)) {
366 ambigsw (buffer, popicmds);
369 printf ("%s unknown -- type \"?\" for help\n", buffer);
383 (void) pop_command ("%s%s", popicmds[i].sw, cp ? cp : "");
384 printf ("%s\n", response);
390 if (pop_command ("%s%s", popicmds[i].sw, cp ? cp : "")
392 printf ("%s\n", response);
395 switch (pop_multiline ()) {
397 (void) strcpy (response, ".");
400 printf ("%s\n", response);
404 printf ("%s\n", response);
414 advise (NULLCP, "missing argument to %s", buffer);
417 retr_action (NULLCP, OK);
418 (void) pop_retr (atoi (++cp), retr_action);
419 retr_action (NULLCP, DONE);
420 printf ("%s\n", response);
432 for (dp = nfs, i = 0; *dp; dp++, i++)
433 if (*dp == '\\' || *dp == '"' || *dp == '\n')
436 if ((ep = malloc ((unsigned) i)) == NULL)
437 adios (NULLCP, "out of memory");
438 for (dp = nfs, fp = ep; *dp; dp++) {
440 *fp++ = '\\', *fp++ = 'n';
443 if (*dp == '"' || *dp == '\\')
449 (void) pop_command ("xtnd scan %d \"%s\"", width, ep);
450 printf ("%s\n", response);
467 static int retr_action (rsp, flag)
478 if ((mp = m_remsg (mp, 0, msgnum = mp -> hghmsg + 1)) == NULL)
479 adios (NULLCP, "unable to allocate folder storage");
481 cp = getcpy (m_name (mp -> hghmsg + 1));
482 if ((fp = fopen (cp, "w+")) == NULL)
483 adios (cp, "unable to write");
484 (void) chmod (cp, m_gmprot ());
490 if (fstat (fileno (fp), &st) != NOTOK && st.st_size > 0) {
491 mp -> msgstats[msgnum] = EXISTS | UNSEEN;
492 mp -> msgflags |= SEQMOD;
495 advise (cp, "write error on");
496 mp -> hghmsg = msgnum;
501 (void) fclose (fp), fp = NULL;
502 free (cp), cp = NULL;
508 fprintf (fp, "%s\n", rsp);
522 if (pop_fd (buf1, buf2) == NOTOK)
523 adios (NULLCP, "%s", response);
526 vec[vecp++] = r1bindex (mshproc, '/');
528 switch (child_id = fork ()) {
530 adios ("fork", "unable to");
533 vec[vecp++] = "-popread";
535 vec[vecp++] = "-popwrite";
537 vec[vecp++] = "-idname";
538 vec[vecp++] = mailname;
539 vec[vecp++] = mailname;
541 (void) execvp (mshproc, vec);
542 fprintf (stderr, "unable to exec ");
547 (void) pidXwait (child_id, mshproc);
556 #include "../zotnet/mts.h"
557 #include "../mts/sendmail/smail.h"
560 static int dselect (d)
561 register struct direct *d;
565 if ((i = strlen (d -> d_name)) < sizeof "smtp"
566 || strncmp (d -> d_name, "smtp", sizeof "smtp" - 1))
568 return ((i -= (sizeof ".bulk" - 1)) > 0
569 && !strcmp (d -> d_name + i, ".bulk"));
573 static int dcompar (d1, d2)
580 if (stat ((*d1) -> d_name, &s1) == NOTOK)
582 if (stat ((*d2) -> d_name, &s2) == NOTOK)
584 return ((int) (s1.st_mtime - s2.st_mtime));
588 static do_bulk (host)
595 struct direct **namelist;
597 if (chdir (bulksw) == NOTOK)
598 adios (bulksw, "unable to change directory to");
600 if ((n = scandir (".", &namelist, dselect, dcompar)) == NOTOK)
601 adios (bulksw, "unable to scan directory");
604 for (i = 0; i < n; i++) {
605 register struct direct *d = namelist[i];
608 if (rp_isbad (retval = sm_init (NULLCP, host, 1, 1, snoop)))
609 adios (NULLCP, "problem initializing server: %s",
615 switch (retval = sm_bulk (d -> d_name)) {
617 if (rp_isbad (retval))
618 adios (NULLCP, "problem delivering msg %s: %s",
619 d -> d_name, rp_string (retval));
624 advise (NULLCP, "msg %s: %s", d -> d_name, rp_string (retval));
633 struct direct **newlist;
635 while ((l = scandir (".", &newlist, dselect, dcompar)) > OK) {
638 for (j = 0; j < l; j++) {
639 register struct direct *d = newlist[j];
641 for (i = 0; i < n; i++)
642 if (strcmp (d -> d_name, namelist[i] -> d_name) == 0)
645 switch (retval = sm_bulk (d -> d_name)) {
647 if (rp_isbad (retval))
648 adios (NULLCP, "problem delivering msg %s: %s",
649 d -> d_name, rp_string (retval));
654 advise (NULLCP, "msg %s: %s", d -> d_name,
663 for (i = 0; i < n; i++)
664 free ((char *) namelist[i]);
665 free ((char *) namelist);
666 namelist = newlist, n = l;
674 if (sm == OK && rp_isbad (retval = sm_end (OK)))
675 adios (NULLCP, "problem finalizing server: %s", rp_string (retval));
677 for (i = 0; i < n; i++)
678 free ((char *) namelist[i]);
679 free ((char *) namelist);
681 free ((char *) namelist);