]>
diplodocus.org Git - nmh/blob - uip/popi.c
3 * popi.c -- POP initiator for MPOP
9 #include <h/fmt_scan.h>
10 #include <h/scansbr.h>
11 #include <zotnet/mts/mts.h>
15 # define RPOPminc(a) (a)
17 # define RPOPminc(a) 0
21 # define APOPminc(a) (a)
23 # define APOPminc(a) 0
27 # define BPOPminc(a) (a)
29 # define BPOPminc(a) 0
33 # define BULKminc(a) (a)
35 # define BULKminc(a) 0
38 static struct swit switches
[] = {
40 { "apop", APOPminc (-4) },
42 { "noapop", APOPminc (-6) },
44 { "auto", BPOPminc(-4) },
46 { "noauto", BPOPminc(-6) },
48 { "bulk directory", BULKminc(-4) },
50 { "form formatfile", 0 },
52 { "format string", 5 },
56 { "mshproc program", 0 },
58 { "rpop", RPOPminc (-4) },
60 { "norpop", RPOPminc (-6) },
64 { "width columns", 0 },
72 static char *bulksw
= NULL
;
75 static char mailname
[BUFSIZ
];
76 static char *nfs
= NULL
;
77 static struct msgs
*mp
;
80 extern char response
[];
85 int sc_width (void); /* from termsbr.c */
89 main (int argc
, char **argv
)
91 int autosw
= 1, noisy
= 1, rpop
;
92 char *cp
, *maildir
, *folder
= NULL
, *form
= NULL
;
93 char *format
= NULL
, *host
= NULL
, *user
= NULL
;
94 char *pass
= NULL
, buf
[BUFSIZ
], **argp
;
98 invo_name
= r1bindex (argv
[0], '/');
100 /* read user profile/context */
103 mts_init (invo_name
);
104 arguments
= getarguments (invo_name
, argc
, argv
, 1);
107 if (pophost
&& *pophost
)
109 if ((cp
= getenv ("MHPOPDEBUG")) && *cp
)
112 rpop
= getuid() && !geteuid();
114 while (cp
= *argp
++) {
116 switch (smatch (++cp
, switches
)) {
118 ambigsw (cp
, switches
);
121 adios (NULL
, "-%s unknown", cp
);
124 snprintf (buf
, sizeof(buf
), "%s [+folder] [switches]",
126 print_help (buf
, switches
, 1);
129 print_version(invo_name
);
140 if (!(bulksw
= *argp
++) || *bulksw
== '-')
141 adios (NULL
, "missing argument to %s", argp
[-2]);
145 if (!(form
= *argp
++) || *form
== '-')
146 adios (NULL
, "missing argument to %s", argp
[-2]);
150 if (!(format
= *argp
++) || *format
== '-')
151 adios (NULL
, "missing argument to %s", argp
[-2]);
156 if (!(cp
= *argp
++) || *cp
== '-')
157 adios (NULL
, "missing argument to %s", argp
[-2]);
162 if (!(host
= *argp
++) || *host
== '-')
163 adios (NULL
, "missing argument to %s", argp
[-2]);
166 if (!(user
= *argp
++) || *user
== '-')
167 adios (NULL
, "missing argument to %s", argp
[-2]);
182 if (!(mshproc
= *argp
++) || *mshproc
== '-')
183 adios (NULL
, "missing argument to %s", argp
[-2]);
186 if (*cp
== '+' || *cp
== '@') {
188 adios (NULL
, "only one folder at a time!");
190 folder
= path (cp
+ 1, *cp
== '+' ? TFOLDER
: TSUBCWF
);
193 adios (NULL
, "usage: %s [+folder] [switches]", invo_name
);
197 adios (NULL
, "usage: %s -host \"host\"", invo_name
);
205 user
= getusername ();
207 pass
= getusername ();
210 ruserpass (host
, &user
, &pass
);
212 snprintf (mailname
, sizeof(mailname
), "PO box for %s@%s", user
, host
);
214 if (pop_init (host
, user
, pass
, snoop
, rpop
) == NOTOK
)
215 adios (NULL
, "%s", response
);
219 /* get new format string */
220 nfs
= new_fs (form
, format
, FORMAT
);
222 if (!context_find ("path"))
223 free (path ("./", TFOLDER
));
225 folder
= getfolder (0);
226 maildir
= m_maildir (folder
);
228 if (stat (maildir
, &st
) == NOTOK
) {
230 adios (maildir
, "error on folder");
231 cp
= concat ("Create folder \"", maildir
, "\"? ", NULL
);
232 if (noisy
&& !getanswer (cp
))
235 if (!makedir (maildir
))
236 adios (NULL
, "unable to create folder %s", maildir
);
239 if (chdir (maildir
) == NOTOK
)
240 adios (maildir
, "unable to change directory to");
242 if (!(mp
= folder_read (folder
)))
243 adios (NULL
, "unable to read folder %s", folder
);
254 context_replace (pfolder
, folder
); /* update current folder */
255 seq_setunseen (mp
, 0); /* set the Unseen-Sequence */
257 context_save (); /* save the context file */
264 static struct swit popicmds
[] = {
307 printf ("(%s) ", invo_name
);
308 for (cp
= buffer
; (i
= getchar ()) != '\n'; ) {
317 if (cp
< buffer
+ sizeof buffer
- 2)
321 if (buffer
[0] == '\0')
323 if (buffer
[0] == '?') {
324 printf ("commands:\n");
325 print_sw (ALL
, popicmds
, "");
326 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name
);
330 if (cp
= strchr (buffer
, ' '))
332 switch (i
= smatch (buffer
, popicmds
)) {
334 ambigsw (buffer
, popicmds
);
337 printf ("%s unknown -- type \"?\" for help\n", buffer
);
351 pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "");
352 printf ("%s\n", response
);
358 if (pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "")
360 printf ("%s\n", response
);
363 switch (pop_multiline ()) {
365 strcpy (response
, ".");
368 printf ("%s\n", response
);
372 printf ("%s\n", response
);
382 advise (NULL
, "missing argument to %s", buffer
);
385 retr_action (NULL
, OK
);
386 pop_retr (atoi (++cp
), retr_action
);
387 retr_action (NULL
, DONE
);
388 printf ("%s\n", response
);
400 for (dp
= nfs
, i
= 0; *dp
; dp
++, i
++)
401 if (*dp
== '\\' || *dp
== '"' || *dp
== '\n')
404 if ((ep
= malloc ((unsigned) i
)) == NULL
)
405 adios (NULL
, "out of memory");
406 for (dp
= nfs
, fp
= ep
; *dp
; dp
++) {
408 *fp
++ = '\\', *fp
++ = 'n';
411 if (*dp
== '"' || *dp
== '\\')
417 pop_command ("xtnd scan %d \"%s\"", width
, ep
);
418 printf ("%s\n", response
);
435 retr_action (char *rsp
, int flag
)
444 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
= mp
->hghmsg
+ 1)))
445 adios (NULL
, "unable to allocate folder storage");
447 cp
= getcpy (m_name (mp
->hghmsg
+ 1));
448 if ((fp
= fopen (cp
, "w+")) == NULL
)
449 adios (cp
, "unable to write");
450 chmod (cp
, m_gmprot ());
456 if (fstat (fileno (fp
), &st
) != NOTOK
&& st
.st_size
> 0) {
457 clear_msg_flags (mp
, msgnum
);
458 set_exists (mp
, msgnum
);
459 set_unseen (mp
, msgnum
);
460 mp
->msgflags
|= SEQMOD
;
463 advise (cp
, "write error on");
469 fclose (fp
), fp
= NULL
;
470 free (cp
), cp
= NULL
;
476 fprintf (fp
, "%s\n", rsp
);
485 char buf1
[BUFSIZ
], buf2
[BUFSIZ
], *vec
[9];
487 if (pop_fd (buf1
, sizeof(buf1
), buf2
, sizeof(buf2
)) == NOTOK
)
488 adios (NULL
, "%s", response
);
491 vec
[vecp
++] = r1bindex (mshproc
, '/');
493 switch (child_id
= fork ()) {
495 adios ("fork", "unable to");
498 vec
[vecp
++] = "-popread";
500 vec
[vecp
++] = "-popwrite";
502 vec
[vecp
++] = "-idname";
503 vec
[vecp
++] = mailname
;
504 vec
[vecp
++] = mailname
;
506 execvp (mshproc
, vec
);
507 fprintf (stderr
, "unable to exec ");
512 pidXwait (child_id
, mshproc
);
520 #include <zotnet/mts/mts.h>
521 #include <mts/smtp/smtp.h>
524 dselect (struct direct
*d
)
528 if ((i
= strlen (d
->d_name
)) < sizeof "smtp"
529 || strncmp (d
->d_name
, "smtp", sizeof "smtp" - 1))
531 return ((i
-= (sizeof ".bulk" - 1)) > 0
532 && !strcmp (d
->d_name
+ i
, ".bulk"));
537 dcompar (struct direct
*d1
, struct direct
*d2
)
541 if (stat ((*d1
)->d_name
, &s1
) == NOTOK
)
543 if (stat ((*d2
)->d_name
, &s2
) == NOTOK
)
545 return ((int) (s1
.st_mtime
- s2
.st_mtime
));
554 struct direct
**namelist
;
556 if (chdir (bulksw
) == NOTOK
)
557 adios (bulksw
, "unable to change directory to");
559 if ((n
= scandir (".", &namelist
, dselect
, dcompar
)) == NOTOK
)
560 adios (bulksw
, "unable to scan directory");
563 for (i
= 0; i
< n
; i
++) {
564 register struct direct
*d
= namelist
[i
];
567 if (rp_isbad (retval
= sm_init (NULL
, host
, 1, 1, snoop
)))
568 adios (NULL
, "problem initializing server: %s",
574 switch (retval
= sm_bulk (d
->d_name
)) {
576 if (rp_isbad (retval
))
577 adios (NULL
, "problem delivering msg %s: %s",
578 d
->d_name
, rp_string (retval
));
583 advise (NULL
, "msg %s: %s", d
->d_name
, rp_string (retval
));
592 struct direct
**newlist
;
594 while ((l
= scandir (".", &newlist
, dselect
, dcompar
)) > OK
) {
597 for (j
= 0; j
< l
; j
++) {
598 register struct direct
*d
= newlist
[j
];
600 for (i
= 0; i
< n
; i
++)
601 if (strcmp (d
->d_name
, namelist
[i
]->d_name
) == 0)
604 switch (retval
= sm_bulk (d
->d_name
)) {
606 if (rp_isbad (retval
))
607 adios (NULL
, "problem delivering msg %s: %s",
608 d
->d_name
, rp_string (retval
));
613 advise (NULL
, "msg %s: %s", d
->d_name
,
622 for (i
= 0; i
< n
; i
++)
623 free ((char *) namelist
[i
]);
624 free ((char *) namelist
);
625 namelist
= newlist
, n
= l
;
633 if (sm
== OK
&& rp_isbad (retval
= sm_end (OK
)))
634 adios (NULL
, "problem finalizing server: %s", rp_string (retval
));
636 for (i
= 0; i
< n
; i
++)
637 free ((char *) namelist
[i
]);
638 free ((char *) namelist
);
640 free ((char *) namelist
);