]>
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>
20 # define RPOPminc(a) (a)
22 # define RPOPminc(a) 0
26 # define APOPminc(a) (a)
28 # define APOPminc(a) 0
32 # define BPOPminc(a) (a)
34 # define BPOPminc(a) 0
38 # define BULKminc(a) (a)
40 # define BULKminc(a) 0
43 static struct swit switches
[] = {
45 { "apop", APOPminc (-4) },
47 { "noapop", APOPminc (-6) },
49 { "auto", BPOPminc(-4) },
51 { "noauto", BPOPminc(-6) },
53 { "bulk directory", BULKminc(-4) },
55 { "form formatfile", 0 },
57 { "format string", 5 },
61 { "mshproc program", 0 },
63 { "rpop", RPOPminc (-4) },
65 { "norpop", RPOPminc (-6) },
69 { "width columns", 0 },
77 static char *bulksw
= NULL
;
80 static char mailname
[BUFSIZ
];
81 static char *nfs
= NULL
;
82 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
= pluspath (cp
);
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
, NULL
, 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 create_folder(maildir
, 0, done
);
234 if (chdir (maildir
) == NOTOK
)
235 adios (maildir
, "unable to change directory to");
237 if (!(mp
= folder_read (folder
)))
238 adios (NULL
, "unable to read folder %s", folder
);
249 context_replace (pfolder
, folder
); /* update current folder */
250 seq_setunseen (mp
, 0); /* set the Unseen-Sequence */
252 context_save (); /* save the context file */
257 static struct swit popicmds
[] = {
300 printf ("(%s) ", invo_name
);
301 for (cp
= buffer
; (i
= getchar ()) != '\n'; ) {
310 if (cp
< buffer
+ sizeof buffer
- 2)
314 if (buffer
[0] == '\0')
316 if (buffer
[0] == '?') {
317 printf ("commands:\n");
318 print_sw (ALL
, popicmds
, "");
319 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name
);
323 if (cp
= strchr (buffer
, ' '))
325 switch (i
= smatch (buffer
, popicmds
)) {
327 ambigsw (buffer
, popicmds
);
330 printf ("%s unknown -- type \"?\" for help\n", buffer
);
344 pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "");
345 printf ("%s\n", response
);
351 if (pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "")
353 printf ("%s\n", response
);
356 switch (pop_multiline ()) {
358 strcpy (response
, ".");
361 printf ("%s\n", response
);
365 printf ("%s\n", response
);
375 advise (NULL
, "missing argument to %s", buffer
);
378 retr_action (NULL
, OK
);
379 pop_retr (atoi (++cp
), retr_action
);
380 retr_action (NULL
, DONE
);
381 printf ("%s\n", response
);
393 for (dp
= nfs
, i
= 0; *dp
; dp
++, i
++)
394 if (*dp
== '\\' || *dp
== '"' || *dp
== '\n')
397 ep
= mh_xmalloc ((unsigned) i
);
398 for (dp
= nfs
, fp
= ep
; *dp
; dp
++) {
400 *fp
++ = '\\', *fp
++ = 'n';
403 if (*dp
== '"' || *dp
== '\\')
409 pop_command ("xtnd scan %d \"%s\"", width
, ep
);
410 printf ("%s\n", response
);
427 retr_action (char *rsp
, int flag
)
436 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
= mp
->hghmsg
+ 1)))
437 adios (NULL
, "unable to allocate folder storage");
439 cp
= getcpy (m_name (mp
->hghmsg
+ 1));
440 if ((fp
= fopen (cp
, "w+")) == NULL
)
441 adios (cp
, "unable to write");
442 chmod (cp
, m_gmprot ());
448 if (fstat (fileno (fp
), &st
) != NOTOK
&& st
.st_size
> 0) {
449 clear_msg_flags (mp
, msgnum
);
450 set_exists (mp
, msgnum
);
451 set_unseen (mp
, msgnum
);
452 mp
->msgflags
|= SEQMOD
;
455 advise (cp
, "write error on");
461 fclose (fp
), fp
= NULL
;
462 free (cp
), cp
= NULL
;
468 fprintf (fp
, "%s\n", rsp
);
477 char buf1
[BUFSIZ
], buf2
[BUFSIZ
], *vec
[9];
479 if (pop_fd (buf1
, sizeof(buf1
), buf2
, sizeof(buf2
)) == NOTOK
)
480 adios (NULL
, "%s", response
);
483 vec
[vecp
++] = r1bindex (mshproc
, '/');
485 switch (child_id
= fork ()) {
487 adios ("fork", "unable to");
490 vec
[vecp
++] = "-popread";
492 vec
[vecp
++] = "-popwrite";
494 vec
[vecp
++] = "-idname";
495 vec
[vecp
++] = mailname
;
496 vec
[vecp
++] = mailname
;
498 execvp (mshproc
, vec
);
499 fprintf (stderr
, "unable to exec ");
504 pidXwait (child_id
, mshproc
);
513 #include <mts/smtp/smtp.h>
516 dselect (struct direct
*d
)
520 if ((i
= strlen (d
->d_name
)) < sizeof "smtp"
521 || strncmp (d
->d_name
, "smtp", sizeof "smtp" - 1))
523 return ((i
-= (sizeof ".bulk" - 1)) > 0
524 && !strcmp (d
->d_name
+ i
, ".bulk"));
529 dcompar (struct direct
*d1
, struct direct
*d2
)
533 if (stat ((*d1
)->d_name
, &s1
) == NOTOK
)
535 if (stat ((*d2
)->d_name
, &s2
) == NOTOK
)
537 return ((int) (s1
.st_mtime
- s2
.st_mtime
));
546 struct direct
**namelist
;
548 if (chdir (bulksw
) == NOTOK
)
549 adios (bulksw
, "unable to change directory to");
551 if ((n
= scandir (".", &namelist
, dselect
, dcompar
)) == NOTOK
)
552 adios (bulksw
, "unable to scan directory");
555 for (i
= 0; i
< n
; i
++) {
556 register struct direct
*d
= namelist
[i
];
559 if (rp_isbad (retval
= sm_init (NULL
, host
, 1, 1, snoop
)))
560 adios (NULL
, "problem initializing server: %s",
566 switch (retval
= sm_bulk (d
->d_name
)) {
568 if (rp_isbad (retval
))
569 adios (NULL
, "problem delivering msg %s: %s",
570 d
->d_name
, rp_string (retval
));
575 advise (NULL
, "msg %s: %s", d
->d_name
, rp_string (retval
));
584 struct direct
**newlist
;
586 while ((l
= scandir (".", &newlist
, dselect
, dcompar
)) > OK
) {
589 for (j
= 0; j
< l
; j
++) {
590 register struct direct
*d
= newlist
[j
];
592 for (i
= 0; i
< n
; i
++)
593 if (strcmp (d
->d_name
, namelist
[i
]->d_name
) == 0)
596 switch (retval
= sm_bulk (d
->d_name
)) {
598 if (rp_isbad (retval
))
599 adios (NULL
, "problem delivering msg %s: %s",
600 d
->d_name
, rp_string (retval
));
605 advise (NULL
, "msg %s: %s", d
->d_name
,
614 for (i
= 0; i
< n
; i
++)
615 free ((char *) namelist
[i
]);
616 free ((char *) namelist
);
617 namelist
= newlist
, n
= l
;
625 if (sm
== OK
&& rp_isbad (retval
= sm_end (OK
)))
626 adios (NULL
, "problem finalizing server: %s", rp_string (retval
));
628 for (i
= 0; i
< n
; i
++)
629 free ((char *) namelist
[i
]);
630 free ((char *) namelist
);
632 free ((char *) namelist
);