Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / popi.c,v
1 head    1.8;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.8
9 date    92.10.28.18.52.45;      author jromine; state Exp;
10 branches;
11 next    1.7;
12
13 1.7
14 date    92.10.28.18.20.47;      author jromine; state Exp;
15 branches;
16 next    1.6;
17
18 1.6
19 date    92.05.20.22.11.32;      author jromine; state Exp;
20 branches;
21 next    1.5;
22
23 1.5
24 date    92.05.19.21.05.55;      author jromine; state Exp;
25 branches;
26 next    1.4;
27
28 1.4
29 date    92.03.03.17.09.57;      author jromine; state Exp;
30 branches;
31 next    1.3;
32
33 1.3
34 date    92.02.08.00.10.26;      author jromine; state Exp;
35 branches;
36 next    1.2;
37
38 1.2
39 date    92.02.04.21.50.37;      author jromine; state Exp;
40 branches;
41 next    1.1;
42
43 1.1
44 date    92.02.04.21.50.14;      author jromine; state Exp;
45 branches;
46 next    ;
47
48
49 desc
50 @from mrose for APOP
51 @
52
53
54 1.8
55 log
56 @h/local.h includes sys/stat.h -- don't include it twice
57 @
58 text
59 @/* popi.c - POP initiator - for MPOP */
60 #ifndef lint
61 static char ident[] = "@@(#)$Id: popi.c,v 1.7 1992/10/28 18:20:47 jromine Exp jromine $";
62 #endif  lint
63
64 #include "../h/mh.h"
65 #include "../h/formatsbr.h"
66 #include "../h/scansbr.h"
67 #include <errno.h>
68 #include <stdio.h>
69 #include <sys/types.h>
70 #ifdef  SMTP
71 #include "../h/local.h"
72 #else   /* SMTP */
73 #include <sys/stat.h>
74 #endif  /* SMTP */
75 #include "../zotnet/mts.h"
76
77 /* \f */
78
79 #ifndef RPOP
80 #define RPOPminc(a)     (a)
81 #else
82 #define RPOPminc(a)     0
83 #endif
84
85 #ifndef APOP
86 #define APOPminc(a)     (a)
87 #else
88 #define APOPminc(a)     0
89 #endif
90
91 #ifndef BPOP
92 #define BPOPminc(a)     (a)
93 #else
94 #define BPOPminc(a)     0
95 #endif
96
97 #ifndef SMTP
98 #define BULKminc(a)     (a)
99 #else
100 #define BULKminc(a)     0
101 #endif
102
103 static struct swit  switches[] = {
104 #define APOPSW  0
105     "apop", APOPminc (-4),
106 #define NAPOPSW 1
107     "noapop", APOPminc (-6),
108
109 #define AUTOSW  2
110     "auto", BPOPminc(-4),
111 #define NAUTOSW 3
112     "noauto", BPOPminc(-6),
113
114 #define BULKSW  4
115     "bulk directory", BULKminc(-4),
116
117 #define FORMSW  5
118     "form formatfile", 0,
119
120 #define FMTSW   6
121     "format string", 5,
122
123 #define HOSTSW  7
124     "host host", 0,
125
126 #define PROGSW  8
127     "mshproc program", 0,
128
129 #define RPOPSW  9
130     "rpop", RPOPminc (-4),
131 #define NRPOPSW 10
132     "norpop", RPOPminc (-6),
133
134 #define USERSW  11
135     "user user", 0,
136
137 #define WIDSW   12
138     "width columns", 0,
139
140 #define HELPSW  13
141     "help", 4,
142
143     NULL, 0
144 };
145
146 /* \f */
147
148 static  char   *bulksw = NULLCP;
149 static  int     snoop = 0;
150 static  int     width = 0;
151
152 static  char    mailname[BUFSIZ];
153
154 static  char   *nfs = NULL;
155
156 static  struct msgs *mp;
157
158 extern  int     errno;
159
160 extern  char    response[];
161
162 /* \f */
163
164 /* ARGSUSED */
165
166 main (argc, argv)
167 int     argc;
168 char   *argv[];
169 {
170     int     autosw = 1,
171             noisy = 1,
172             rpop;
173     char   *cp,
174            *maildir,
175            *folder = NULL,
176            *form = NULL,
177            *format = NULL,
178            *host = NULL,
179            *user = NULL,
180            *pass = NULL,
181             buf[100],
182           **ap,
183           **argp,
184            *arguments[MAXARGS];
185     struct stat st;
186
187     invo_name = r1bindex (argv[0], '/');
188     mts_init (invo_name);
189     if (pophost && *pophost)
190         host = pophost;
191     if ((cp = getenv ("MHPOPDEBUG")) && *cp)
192         snoop++;
193     if ((cp = m_find (invo_name)) != NULL) {
194         ap = brkstring (cp = getcpy (cp), " ", "\n");
195         ap = copyip (ap, arguments);
196     }
197     else
198         ap = arguments;
199     (void) copyip (argv + 1, ap);
200     argp = arguments;
201
202     rpop = getuid () && !geteuid ();
203
204 /* \f */
205
206     while (cp = *argp++) {
207         if (*cp == '-')
208             switch (smatch (++cp, switches)) {
209                 case AMBIGSW: 
210                     ambigsw (cp, switches);
211                     done (1);
212                 case UNKWNSW: 
213                     adios (NULLCP, "-%s unknown", cp);
214                 case HELPSW: 
215                     (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
216                     help (buf, switches);
217                     done (1);
218
219                 case AUTOSW:
220                     autosw = 1;
221                     continue;
222                 case NAUTOSW:
223                     autosw = 0;
224                     continue;
225
226                 case BULKSW: 
227                     if (!(bulksw = *argp++) || *bulksw == '-')
228                         adios (NULLCP, "missing argument to %s", argp[-2]);
229                     continue;
230
231                 case FORMSW: 
232                     if (!(form = *argp++) || *form == '-')
233                         adios (NULLCP, "missing argument to %s", argp[-2]);
234                     format = NULL;
235                     continue;
236                 case FMTSW: 
237                     if (!(format = *argp++) || *format == '-')
238                         adios (NULLCP, "missing argument to %s", argp[-2]);
239                     form = NULL;
240                     continue;
241
242                 case WIDSW: 
243                     if (!(cp = *argp++) || *cp == '-')
244                         adios (NULLCP, "missing argument to %s", argp[-2]);
245                     width = atoi (cp);
246                     continue;
247
248                 case HOSTSW:
249                     if (!(host = *argp++) || *host == '-')
250                         adios (NULLCP, "missing argument to %s", argp[-2]);
251                     continue;
252                 case USERSW:
253                     if (!(user = *argp++) || *user == '-')
254                         adios (NULLCP, "missing argument to %s", argp[-2]);
255                     continue;
256
257                 case APOPSW:
258                     rpop = -1;
259                     continue;
260                 case RPOPSW:
261                     rpop = 1;
262                     continue;
263                 case NAPOPSW:
264                 case NRPOPSW:
265                     rpop = 0;
266                     continue;
267
268                 case PROGSW:
269                     if (!(mshproc = *argp++) || *mshproc == '-')
270                         adios (NULLCP, "missing argument to %s", argp[-2]);
271                     continue;
272             }
273         if (*cp == '+' || *cp == '@@') {
274             if (folder)
275                 adios (NULLCP, "only one folder at a time!");
276             else
277                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
278         }
279         else
280             adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
281     }
282
283 /* \f */
284
285     if (!host)
286         adios (NULLCP, "usage: %s -host \"host\"", invo_name);
287
288 #ifdef  SMTP
289     if (bulksw)
290         do_bulk (host);
291 #endif
292
293     if (user == NULL)
294         user = getusr ();
295     if (rpop > 0)
296         pass = getusr ();
297     else {
298         (void) setuid (getuid ());
299         ruserpass (host, &user, &pass);
300     }
301     (void) sprintf (mailname, "PO box for %s@@%s", user, host);
302
303     if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
304         adios (NULLCP, "%s", response);
305     if (rpop > 0)
306         (void) setuid (getuid ());
307
308     nfs = new_fs (form, format, FORMAT);
309
310     if (!m_find ("path"))
311         free (path ("./", TFOLDER));
312     if (!folder && !(folder = m_find (inbox)))
313         folder = defalt;
314     maildir = m_maildir (folder);
315
316     if (stat (maildir, &st) == NOTOK) {
317         if (errno != ENOENT)
318             adios (maildir, "error on folder");
319         cp = concat ("Create folder \"", maildir, "\"? ", NULLCP);
320         if (noisy && !getanswer (cp))
321             done (1);
322         free (cp);
323         if (!makedir (maildir))
324             adios (NULLCP, "unable to create folder %s", maildir);
325     }
326
327     if (chdir (maildir) == NOTOK)
328         adios (maildir, "unable to change directory to");
329     if (!(mp = m_gmsg (folder)))
330         adios (NULLCP, "unable to read folder %s", folder);
331
332 #ifdef  BPOP
333     if (autosw)
334         msh ();
335     else
336 #endif
337         popi ();
338
339     (void) pop_quit ();
340
341     m_replace (pfolder, folder);
342     m_setvis (mp, 0);
343     m_sync (mp);
344     m_update ();
345
346     done (0);
347
348     /* NOTREACHED */
349 }
350
351 /* \f */
352
353 static struct swit popicmds[] = {
354 #define DELECMD  0
355     "dele", 0,
356 #define LASTCMD  1
357     "last", 0,
358 #define LISTCMD  2
359     "list", 0,
360 #define NOOPCMD  3
361     "noop", 0,
362 #define QUITCMD  4
363     "quit", 0,
364 #define RETRCMD  5
365     "retr", 0,
366 #define RSETCMD  6
367     "rset", 0,
368 #define SCANCMD  7
369     "scan", 0,
370 #define STATCMD  8
371     "stat", 0,
372 #define TOPCMD   9
373     "top", 0,
374 #ifdef  BPOP
375 #define MSHCMD  10
376     "msh", 0,
377 #endif
378
379     NULL, 0
380 };
381
382 /* \f */
383
384 static  popi ()
385 {
386     int     eof;
387
388     eof = 0;
389     for (;;) {
390         int     i;
391         register char *cp;
392         char    buffer[BUFSIZ];
393
394         if (eof)
395             return;
396
397         printf ("(%s) ", invo_name);
398         for (cp = buffer; (i = getchar ()) != '\n'; ) {
399             if (i == EOF) {
400                 (void) putchar ('\n');
401                 if (cp == buffer)
402                     return;
403                 eof = 1;
404                 break;
405             }
406
407             if (cp < buffer + sizeof buffer - 2)
408                 *cp++ = i;
409         }
410         *cp = '\0';
411         if (buffer[0] == '\0')
412             continue;
413         if (buffer[0] == '?') {
414             printf ("commands:\n");
415             printsw (ALL, popicmds, "");
416             printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name);
417             continue;
418         }
419
420         if (cp = index (buffer, ' '))
421             *cp = '\0';
422         switch (i = smatch (buffer, popicmds)) {
423             case AMBIGSW:
424                 ambigsw (buffer, popicmds);
425                 continue;
426             case UNKWNSW:
427                 printf ("%s unknown -- type \"?\" for help\n", buffer);
428                 continue;
429                 
430             case QUITCMD:
431                 return;
432
433             case STATCMD:
434             case DELECMD:
435             case NOOPCMD:
436             case LASTCMD:
437             case RSETCMD:
438             case TOPCMD:
439                 if (cp)
440                     *cp = ' ';
441                 (void) pop_command ("%s%s", popicmds[i].sw, cp ? cp : "");
442                 printf ("%s\n", response);
443                 break;          
444
445             case LISTCMD:
446                 if (cp)
447                     *cp = ' ';
448                 if (pop_command ("%s%s", popicmds[i].sw, cp ? cp : "")
449                         == OK) {
450                     printf ("%s\n", response);
451                     if (!cp)
452                         for (;;) {
453                             switch (pop_multiline ()) {
454                                 case DONE:
455                                     (void) strcpy (response, ".");
456                                     /* and fall... */
457                                 case NOTOK:
458                                     printf ("%s\n", response);
459                                     break;
460
461                                 case OK:
462                                     printf ("%s\n", response);
463                                     continue;
464                              }
465                             break;
466                         }
467                 }
468                 break;
469
470             case RETRCMD:
471                 if (!cp) {
472                     advise (NULLCP, "missing argument to %s", buffer);
473                     break;
474                 }
475                 retr_action (NULLCP, OK);
476                 (void) pop_retr (atoi (++cp), retr_action);
477                 retr_action (NULLCP, DONE);
478                 printf ("%s\n", response);
479                 break;
480
481             case SCANCMD:
482                 {
483                     char   *dp,
484                            *ep,
485                            *fp;
486
487                     if (width == 0)
488                         width = sc_width ();
489
490                     for (dp = nfs, i = 0; *dp; dp++, i++)
491                         if (*dp == '\\' || *dp == '"' || *dp == '\n')
492                             i++;
493                     i++;
494                     if ((ep = malloc ((unsigned) i)) == NULL)
495                         adios (NULLCP, "out of memory");
496                     for (dp = nfs, fp = ep; *dp; dp++) {
497                         if (*dp == '\n') {
498                             *fp++ = '\\', *fp++ = 'n';
499                             continue;
500                         }
501                         if (*dp == '"' || *dp == '\\')
502                             *fp++ = '\\';
503                         *fp++ = *dp;
504                     }
505                     *fp = '\0';
506
507                     (void) pop_command ("xtnd scan %d \"%s\"", width, ep);
508                     printf ("%s\n", response);
509
510                     free (ep);
511                 }
512                 break;
513
514 #ifdef  BPOP
515             case MSHCMD:
516                 msh ();
517                 break;
518 #endif
519         }
520     }
521 }
522
523 /* \f */
524
525 static int  retr_action (rsp, flag)
526 char   *rsp;
527 int     flag;
528 {
529     static FILE    *fp;
530
531     if (rsp == NULL) {
532         static int    msgnum;
533         static char  *cp;
534
535         if (flag == OK) {
536             if ((mp = m_remsg (mp, 0, msgnum = mp -> hghmsg + 1)) == NULL)
537                 adios (NULLCP, "unable to allocate folder storage");
538
539             cp = getcpy (m_name (mp -> hghmsg + 1));
540             if ((fp = fopen (cp, "w+")) == NULL)
541                 adios (cp, "unable to write");
542             (void) chmod (cp, m_gmprot ());
543         }
544         else {
545             struct stat st;
546
547             (void) fflush (fp);
548             if (fstat (fileno (fp), &st) != NOTOK && st.st_size > 0) {
549                 mp -> msgstats[msgnum] = EXISTS | UNSEEN;
550                 mp -> msgflags |= SEQMOD;
551
552                 if (ferror (fp))
553                     advise (cp, "write error on");
554                 mp -> hghmsg = msgnum;
555             }
556             else
557                 (void) unlink (cp);
558
559             (void) fclose (fp), fp = NULL;
560             free (cp), cp = NULL;
561         }
562
563         return;
564     }
565
566     fprintf (fp, "%s\n", rsp);
567 }
568
569 /* \f */
570
571 #ifdef  BPOP
572 static  msh ()
573 {
574     int     child_id,
575             vecp;
576     char    buf1[BUFSIZ],
577             buf2[BUFSIZ],
578            *vec[9];
579
580     if (pop_fd (buf1, buf2) == NOTOK)
581         adios (NULLCP, "%s", response);
582
583     vecp = 0;
584     vec[vecp++] = r1bindex (mshproc, '/');
585                     
586     switch (child_id = fork ()) {
587         case NOTOK:
588             adios ("fork", "unable to");
589
590         case OK:
591             vec[vecp++] = "-popread";
592             vec[vecp++] = buf1;
593             vec[vecp++] = "-popwrite";
594             vec[vecp++] = buf2;
595             vec[vecp++] = "-idname";
596             vec[vecp++] = mailname;
597             vec[vecp++] = mailname;
598             vec[vecp] = NULL;
599             (void) execvp (mshproc, vec);
600             fprintf (stderr, "unable to exec ");
601             perror (mshproc);
602             _exit (-1);
603
604        default:
605             (void) pidXwait (child_id, mshproc);
606             break;
607    }
608 }
609 #endif
610
611 /* \f */
612
613 #ifdef  SMTP
614 #include "../zotnet/mts.h"
615 #include "../mts/sendmail/smail.h"
616
617
618 static int  dselect (d)
619 register struct direct *d;
620 {
621     int     i;
622
623     if ((i = strlen (d -> d_name)) < sizeof "smtp"
624             || strncmp (d -> d_name, "smtp", sizeof "smtp" - 1))
625         return 0;
626     return ((i -= (sizeof ".bulk" - 1)) > 0
627                 && !strcmp (d -> d_name + i, ".bulk"));
628 }
629
630
631 static int  dcompar (d1, d2)
632 struct direct **d1,
633               **d2;
634 {
635     struct stat s1,
636                 s2;
637
638     if (stat ((*d1) -> d_name, &s1) == NOTOK)
639         return 1;
640     if (stat ((*d2) -> d_name, &s2) == NOTOK)
641         return -1;
642     return ((int) (s1.st_mtime - s2.st_mtime));
643 }
644
645
646 static  do_bulk (host)
647 char   *host;
648 {
649     register int    i;
650     int     n,
651             retval,
652             sm;
653     struct direct **namelist;
654
655     if (chdir (bulksw) == NOTOK)
656         adios (bulksw, "unable to change directory to");
657
658     if ((n = scandir (".", &namelist, dselect, dcompar)) == NOTOK)
659         adios (bulksw, "unable to scan directory");
660
661     sm = NOTOK;
662     for (i = 0; i < n; i++) {
663         register struct direct *d = namelist[i];
664
665         if (sm == NOTOK) {
666             if (rp_isbad (retval = sm_init (NULLCP, host, 1, 1, snoop)))
667                 adios (NULLCP, "problem initializing server: %s",
668                        rp_string (retval));
669             else
670                 sm = OK;
671         }
672
673         switch (retval = sm_bulk (d -> d_name)) {
674             default:
675                 if (rp_isbad (retval))
676                     adios (NULLCP, "problem delivering msg %s: %s",
677                            d -> d_name, rp_string (retval));
678                 /* else fall... */
679             case RP_OK:
680             case RP_NO:
681             case RP_NDEL:
682                 advise (NULLCP, "msg %s: %s", d -> d_name, rp_string (retval));
683                 break;
684         }
685     }
686
687     if (sm == OK) {
688         register int j;
689         int     l,
690                 m;
691         struct direct **newlist;
692
693         while ((l = scandir (".", &newlist, dselect, dcompar)) > OK) {
694             m = 0;
695
696             for (j = 0; j < l; j++) {
697                 register struct direct *d = newlist[j];
698
699                 for (i = 0; i < n; i++)
700                     if (strcmp (d -> d_name, namelist[i] -> d_name) == 0)
701                         break;
702                 if (i >= n) {
703                     switch (retval = sm_bulk (d -> d_name)) {
704                         default:
705                             if (rp_isbad (retval))
706                                 adios (NULLCP, "problem delivering msg %s: %s",
707                                        d -> d_name, rp_string (retval));
708                             /* else fall... */
709                         case RP_OK:
710                         case RP_NO:
711                         case RP_NDEL:
712                             advise (NULLCP, "msg %s: %s", d -> d_name,
713                                     rp_string (retval));
714                             break;
715                     }
716
717                     m = 1;
718                 }
719             }
720
721             for (i = 0; i < n; i++)
722                 free ((char *) namelist[i]);
723             free ((char *) namelist);
724             namelist = newlist, n = l;
725
726             if (!m)
727                 break;
728             newlist = NULL;
729         }
730     }
731
732     if (sm == OK && rp_isbad (retval = sm_end (OK)))
733         adios (NULLCP, "problem finalizing server: %s", rp_string (retval));
734
735     for (i = 0; i < n; i++)
736         free ((char *) namelist[i]);
737     free ((char *) namelist);
738
739     free ((char *) namelist);
740
741     done (0);
742 }
743 #endif
744 @
745
746
747 1.7
748 log
749 @fix for Inbox:
750 @
751 text
752 @d3 1
753 a3 1
754 static char ident[] = "@@(#)$Id: popi.c,v 1.6 1992/05/20 22:11:32 jromine Exp jromine $";
755 d12 3
756 d16 1
757 a555 1
758 #include "../h/local.h"
759 @
760
761
762 1.6
763 log
764 @MPOP
765 @
766 text
767 @d3 1
768 a3 1
769 static char ident[] = "@@(#)$Id: popi.c,v 1.5 1992/05/19 21:05:55 jromine Exp jromine $";
770 d250 1
771 a250 1
772     if (!folder)
773 @
774
775
776 1.5
777 log
778 @AIX
779 @
780 text
781 @d1 1
782 a1 1
783 /* popi.c - POP initiator */
784 d3 1
785 a3 1
786 static char ident[] = "@@(#)$Id: popi.c,v 1.4 1992/03/03 17:09:57 jromine Exp jromine $";
787 @
788
789
790 1.4
791 log
792 @fixes from mtr
793 @
794 text
795 @d3 1
796 a3 1
797 static char ident[] = "@@(#)$Id: popi.c,v 1.3 1992/02/08 00:10:26 jromine Exp jromine $";
798 d81 1
799 a81 1
800     NULL, NULL
801 d317 1
802 a317 1
803     NULL, NULL
804 d348 2
805 a349 2
806         *cp = NULL;
807         if (buffer[0] == NULL)
808 d359 1
809 a359 1
810             *cp = NULL;
811 d443 1
812 a443 1
813                     *fp = NULL;
814 @
815
816
817 1.3
818 log
819 @fixes from mrose
820 @
821 text
822 @d3 1
823 a3 1
824 static char ident[] = "@@(#)$Id: popi.c,v 1.2 1992/02/04 21:50:37 jromine Exp jromine $";
825 d35 6
826 d52 4
827 a55 1
828 #define FORMSW  4
829 d58 1
830 a58 1
831 #define FMTSW   5
832 d61 1
833 a61 1
834 #define HOSTSW  6
835 d64 1
836 a64 1
837 #define PROGSW  7
838 d67 1
839 a67 1
840 #define RPOPSW  8
841 d69 1
842 a69 1
843 #define NRPOPSW 9
844 d72 1
845 a72 1
846 #define USERSW  10
847 d75 1
848 a75 1
849 #define WIDSW   11
850 d78 1
851 a78 1
852 #define HELPSW  12
853 d86 2
854 d110 1
855 a110 2
856             rpop,
857             snoop = 0;
858 d164 5
859 d226 5
860 d546 135
861 @
862
863
864 1.2
865 log
866 @contributed patch
867 @
868 text
869 @d3 1
870 a3 1
871 static char ident[] = "@@(#)$Id: scan.c,v 1.11 1992/02/03 22:45:20 jromine Exp $";
872 d219 1
873 a219 1
874     (void) sprintf (mailname, "POB/%s@@%s", user, host);
875 @
876
877
878 1.1
879 log
880 @Initial revision
881 @
882 text
883 @d2 3
884 a182 4
885                 case NAPOPSW:
886                     rpop = 0;
887                     continue;
888
889 d184 1
890 a184 1
891                     rpop++;
892 d186 1
893 @