]>
diplodocus.org Git - nmh/blob - uip/popi.c
3 * popi.c -- POP initiator for MPOP
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
13 #include <h/fmt_scan.h>
14 #include <h/scansbr.h>
19 # define RPOPminc(a) (a)
21 # define RPOPminc(a) 0
25 # define APOPminc(a) (a)
27 # define APOPminc(a) 0
31 # define BPOPminc(a) (a)
33 # define BPOPminc(a) 0
37 # define BULKminc(a) (a)
39 # define BULKminc(a) 0
42 static struct swit switches
[] = {
44 { "apop", APOPminc (-4) },
46 { "noapop", APOPminc (-6) },
48 { "auto", BPOPminc(-4) },
50 { "noauto", BPOPminc(-6) },
52 { "bulk directory", BULKminc(-4) },
54 { "form formatfile", 0 },
56 { "format string", 5 },
60 { "mshproc program", 0 },
62 { "rpop", RPOPminc (-4) },
64 { "norpop", RPOPminc (-6) },
68 { "width columns", 0 },
76 static char *bulksw
= NULL
;
79 static char mailname
[BUFSIZ
];
80 static char *nfs
= NULL
;
81 static struct msgs
*mp
;
84 extern char response
[];
89 int sc_width (void); /* from termsbr.c */
93 main (int argc
, char **argv
)
95 int autosw
= 1, noisy
= 1, rpop
;
96 char *cp
, *maildir
, *folder
= NULL
, *form
= NULL
;
97 char *format
= NULL
, *host
= NULL
, *user
= NULL
;
98 char *pass
= NULL
, buf
[BUFSIZ
], **argp
;
102 invo_name
= r1bindex (argv
[0], '/');
104 /* read user profile/context */
107 mts_init (invo_name
);
108 arguments
= getarguments (invo_name
, argc
, argv
, 1);
111 if (pophost
&& *pophost
)
113 if ((cp
= getenv ("MHPOPDEBUG")) && *cp
)
116 rpop
= getuid() && !geteuid();
118 while (cp
= *argp
++) {
120 switch (smatch (++cp
, switches
)) {
122 ambigsw (cp
, switches
);
125 adios (NULL
, "-%s unknown", cp
);
128 snprintf (buf
, sizeof(buf
), "%s [+folder] [switches]",
130 print_help (buf
, switches
, 1);
133 print_version(invo_name
);
144 if (!(bulksw
= *argp
++) || *bulksw
== '-')
145 adios (NULL
, "missing argument to %s", argp
[-2]);
149 if (!(form
= *argp
++) || *form
== '-')
150 adios (NULL
, "missing argument to %s", argp
[-2]);
154 if (!(format
= *argp
++) || *format
== '-')
155 adios (NULL
, "missing argument to %s", argp
[-2]);
160 if (!(cp
= *argp
++) || *cp
== '-')
161 adios (NULL
, "missing argument to %s", argp
[-2]);
166 if (!(host
= *argp
++) || *host
== '-')
167 adios (NULL
, "missing argument to %s", argp
[-2]);
170 if (!(user
= *argp
++) || *user
== '-')
171 adios (NULL
, "missing argument to %s", argp
[-2]);
186 if (!(mshproc
= *argp
++) || *mshproc
== '-')
187 adios (NULL
, "missing argument to %s", argp
[-2]);
190 if (*cp
== '+' || *cp
== '@') {
192 adios (NULL
, "only one folder at a time!");
194 folder
= path (cp
+ 1, *cp
== '+' ? TFOLDER
: TSUBCWF
);
197 adios (NULL
, "usage: %s [+folder] [switches]", invo_name
);
201 adios (NULL
, "usage: %s -host \"host\"", invo_name
);
209 user
= getusername ();
211 pass
= getusername ();
214 ruserpass (host
, &user
, &pass
);
216 snprintf (mailname
, sizeof(mailname
), "PO box for %s@%s", user
, host
);
218 if (pop_init (host
, user
, pass
, snoop
, rpop
) == NOTOK
)
219 adios (NULL
, "%s", response
);
223 /* get new format string */
224 nfs
= new_fs (form
, format
, FORMAT
);
226 if (!context_find ("path"))
227 free (path ("./", TFOLDER
));
229 folder
= getfolder (0);
230 maildir
= m_maildir (folder
);
232 if (stat (maildir
, &st
) == NOTOK
) {
234 adios (maildir
, "error on folder");
235 cp
= concat ("Create folder \"", maildir
, "\"? ", NULL
);
236 if (noisy
&& !getanswer (cp
))
239 if (!makedir (maildir
))
240 adios (NULL
, "unable to create folder %s", maildir
);
243 if (chdir (maildir
) == NOTOK
)
244 adios (maildir
, "unable to change directory to");
246 if (!(mp
= folder_read (folder
)))
247 adios (NULL
, "unable to read folder %s", folder
);
258 context_replace (pfolder
, folder
); /* update current folder */
259 seq_setunseen (mp
, 0); /* set the Unseen-Sequence */
261 context_save (); /* save the context file */
266 static struct swit popicmds
[] = {
309 printf ("(%s) ", invo_name
);
310 for (cp
= buffer
; (i
= getchar ()) != '\n'; ) {
319 if (cp
< buffer
+ sizeof buffer
- 2)
323 if (buffer
[0] == '\0')
325 if (buffer
[0] == '?') {
326 printf ("commands:\n");
327 print_sw (ALL
, popicmds
, "");
328 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name
);
332 if (cp
= strchr (buffer
, ' '))
334 switch (i
= smatch (buffer
, popicmds
)) {
336 ambigsw (buffer
, popicmds
);
339 printf ("%s unknown -- type \"?\" for help\n", buffer
);
353 pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "");
354 printf ("%s\n", response
);
360 if (pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "")
362 printf ("%s\n", response
);
365 switch (pop_multiline ()) {
367 strcpy (response
, ".");
370 printf ("%s\n", response
);
374 printf ("%s\n", response
);
384 advise (NULL
, "missing argument to %s", buffer
);
387 retr_action (NULL
, OK
);
388 pop_retr (atoi (++cp
), retr_action
);
389 retr_action (NULL
, DONE
);
390 printf ("%s\n", response
);
402 for (dp
= nfs
, i
= 0; *dp
; dp
++, i
++)
403 if (*dp
== '\\' || *dp
== '"' || *dp
== '\n')
406 if ((ep
= malloc ((unsigned) i
)) == NULL
)
407 adios (NULL
, "out of memory");
408 for (dp
= nfs
, fp
= ep
; *dp
; dp
++) {
410 *fp
++ = '\\', *fp
++ = 'n';
413 if (*dp
== '"' || *dp
== '\\')
419 pop_command ("xtnd scan %d \"%s\"", width
, ep
);
420 printf ("%s\n", response
);
437 retr_action (char *rsp
, int flag
)
446 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
= mp
->hghmsg
+ 1)))
447 adios (NULL
, "unable to allocate folder storage");
449 cp
= getcpy (m_name (mp
->hghmsg
+ 1));
450 if ((fp
= fopen (cp
, "w+")) == NULL
)
451 adios (cp
, "unable to write");
452 chmod (cp
, m_gmprot ());
458 if (fstat (fileno (fp
), &st
) != NOTOK
&& st
.st_size
> 0) {
459 clear_msg_flags (mp
, msgnum
);
460 set_exists (mp
, msgnum
);
461 set_unseen (mp
, msgnum
);
462 mp
->msgflags
|= SEQMOD
;
465 advise (cp
, "write error on");
471 fclose (fp
), fp
= NULL
;
472 free (cp
), cp
= NULL
;
478 fprintf (fp
, "%s\n", rsp
);
487 char buf1
[BUFSIZ
], buf2
[BUFSIZ
], *vec
[9];
489 if (pop_fd (buf1
, sizeof(buf1
), buf2
, sizeof(buf2
)) == NOTOK
)
490 adios (NULL
, "%s", response
);
493 vec
[vecp
++] = r1bindex (mshproc
, '/');
495 switch (child_id
= fork ()) {
497 adios ("fork", "unable to");
500 vec
[vecp
++] = "-popread";
502 vec
[vecp
++] = "-popwrite";
504 vec
[vecp
++] = "-idname";
505 vec
[vecp
++] = mailname
;
506 vec
[vecp
++] = mailname
;
508 execvp (mshproc
, vec
);
509 fprintf (stderr
, "unable to exec ");
514 pidXwait (child_id
, mshproc
);
523 #include <mts/smtp/smtp.h>
526 dselect (struct direct
*d
)
530 if ((i
= strlen (d
->d_name
)) < sizeof "smtp"
531 || strncmp (d
->d_name
, "smtp", sizeof "smtp" - 1))
533 return ((i
-= (sizeof ".bulk" - 1)) > 0
534 && !strcmp (d
->d_name
+ i
, ".bulk"));
539 dcompar (struct direct
*d1
, struct direct
*d2
)
543 if (stat ((*d1
)->d_name
, &s1
) == NOTOK
)
545 if (stat ((*d2
)->d_name
, &s2
) == NOTOK
)
547 return ((int) (s1
.st_mtime
- s2
.st_mtime
));
556 struct direct
**namelist
;
558 if (chdir (bulksw
) == NOTOK
)
559 adios (bulksw
, "unable to change directory to");
561 if ((n
= scandir (".", &namelist
, dselect
, dcompar
)) == NOTOK
)
562 adios (bulksw
, "unable to scan directory");
565 for (i
= 0; i
< n
; i
++) {
566 register struct direct
*d
= namelist
[i
];
569 if (rp_isbad (retval
= sm_init (NULL
, host
, 1, 1, snoop
)))
570 adios (NULL
, "problem initializing server: %s",
576 switch (retval
= sm_bulk (d
->d_name
)) {
578 if (rp_isbad (retval
))
579 adios (NULL
, "problem delivering msg %s: %s",
580 d
->d_name
, rp_string (retval
));
585 advise (NULL
, "msg %s: %s", d
->d_name
, rp_string (retval
));
594 struct direct
**newlist
;
596 while ((l
= scandir (".", &newlist
, dselect
, dcompar
)) > OK
) {
599 for (j
= 0; j
< l
; j
++) {
600 register struct direct
*d
= newlist
[j
];
602 for (i
= 0; i
< n
; i
++)
603 if (strcmp (d
->d_name
, namelist
[i
]->d_name
) == 0)
606 switch (retval
= sm_bulk (d
->d_name
)) {
608 if (rp_isbad (retval
))
609 adios (NULL
, "problem delivering msg %s: %s",
610 d
->d_name
, rp_string (retval
));
615 advise (NULL
, "msg %s: %s", d
->d_name
,
624 for (i
= 0; i
< n
; i
++)
625 free ((char *) namelist
[i
]);
626 free ((char *) namelist
);
627 namelist
= newlist
, n
= l
;
635 if (sm
== OK
&& rp_isbad (retval
= sm_end (OK
)))
636 adios (NULL
, "problem finalizing server: %s", rp_string (retval
));
638 for (i
= 0; i
< n
; i
++)
639 free ((char *) namelist
[i
]);
640 free ((char *) namelist
);
642 free ((char *) namelist
);