]>
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
;
83 extern char response
[];
88 int sc_width (void); /* from termsbr.c */
92 main (int argc
, char **argv
)
94 int autosw
= 1, noisy
= 1, rpop
;
95 char *cp
, *maildir
, *folder
= NULL
, *form
= NULL
;
96 char *format
= NULL
, *host
= NULL
, *user
= NULL
;
97 char *pass
= NULL
, buf
[BUFSIZ
], **argp
;
101 invo_name
= r1bindex (argv
[0], '/');
103 /* read user profile/context */
106 mts_init (invo_name
);
107 arguments
= getarguments (invo_name
, argc
, argv
, 1);
110 if (pophost
&& *pophost
)
112 if ((cp
= getenv ("MHPOPDEBUG")) && *cp
)
115 rpop
= getuid() && !geteuid();
117 while (cp
= *argp
++) {
119 switch (smatch (++cp
, switches
)) {
121 ambigsw (cp
, switches
);
124 adios (NULL
, "-%s unknown", cp
);
127 snprintf (buf
, sizeof(buf
), "%s [+folder] [switches]",
129 print_help (buf
, switches
, 1);
132 print_version(invo_name
);
143 if (!(bulksw
= *argp
++) || *bulksw
== '-')
144 adios (NULL
, "missing argument to %s", argp
[-2]);
148 if (!(form
= *argp
++) || *form
== '-')
149 adios (NULL
, "missing argument to %s", argp
[-2]);
153 if (!(format
= *argp
++) || *format
== '-')
154 adios (NULL
, "missing argument to %s", argp
[-2]);
159 if (!(cp
= *argp
++) || *cp
== '-')
160 adios (NULL
, "missing argument to %s", argp
[-2]);
165 if (!(host
= *argp
++) || *host
== '-')
166 adios (NULL
, "missing argument to %s", argp
[-2]);
169 if (!(user
= *argp
++) || *user
== '-')
170 adios (NULL
, "missing argument to %s", argp
[-2]);
185 if (!(mshproc
= *argp
++) || *mshproc
== '-')
186 adios (NULL
, "missing argument to %s", argp
[-2]);
189 if (*cp
== '+' || *cp
== '@') {
191 adios (NULL
, "only one folder at a time!");
193 folder
= path (cp
+ 1, *cp
== '+' ? TFOLDER
: TSUBCWF
);
196 adios (NULL
, "usage: %s [+folder] [switches]", invo_name
);
200 adios (NULL
, "usage: %s -host \"host\"", invo_name
);
208 user
= getusername ();
210 pass
= getusername ();
213 ruserpass (host
, &user
, &pass
);
215 snprintf (mailname
, sizeof(mailname
), "PO box for %s@%s", user
, host
);
217 if (pop_init (host
, user
, pass
, NULL
, snoop
, rpop
) == NOTOK
)
218 adios (NULL
, "%s", response
);
222 /* get new format string */
223 nfs
= new_fs (form
, format
, FORMAT
);
225 if (!context_find ("path"))
226 free (path ("./", TFOLDER
));
228 folder
= getfolder (0);
229 maildir
= m_maildir (folder
);
231 if (stat (maildir
, &st
) == NOTOK
) {
233 adios (maildir
, "error on folder");
234 cp
= concat ("Create folder \"", maildir
, "\"? ", NULL
);
235 if (noisy
&& !getanswer (cp
))
238 if (!makedir (maildir
))
239 adios (NULL
, "unable to create folder %s", maildir
);
242 if (chdir (maildir
) == NOTOK
)
243 adios (maildir
, "unable to change directory to");
245 if (!(mp
= folder_read (folder
)))
246 adios (NULL
, "unable to read folder %s", folder
);
257 context_replace (pfolder
, folder
); /* update current folder */
258 seq_setunseen (mp
, 0); /* set the Unseen-Sequence */
260 context_save (); /* save the context file */
265 static struct swit popicmds
[] = {
308 printf ("(%s) ", invo_name
);
309 for (cp
= buffer
; (i
= getchar ()) != '\n'; ) {
318 if (cp
< buffer
+ sizeof buffer
- 2)
322 if (buffer
[0] == '\0')
324 if (buffer
[0] == '?') {
325 printf ("commands:\n");
326 print_sw (ALL
, popicmds
, "");
327 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name
);
331 if (cp
= strchr (buffer
, ' '))
333 switch (i
= smatch (buffer
, popicmds
)) {
335 ambigsw (buffer
, popicmds
);
338 printf ("%s unknown -- type \"?\" for help\n", buffer
);
352 pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "");
353 printf ("%s\n", response
);
359 if (pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "")
361 printf ("%s\n", response
);
364 switch (pop_multiline ()) {
366 strcpy (response
, ".");
369 printf ("%s\n", response
);
373 printf ("%s\n", response
);
383 advise (NULL
, "missing argument to %s", buffer
);
386 retr_action (NULL
, OK
);
387 pop_retr (atoi (++cp
), retr_action
);
388 retr_action (NULL
, DONE
);
389 printf ("%s\n", response
);
401 for (dp
= nfs
, i
= 0; *dp
; dp
++, i
++)
402 if (*dp
== '\\' || *dp
== '"' || *dp
== '\n')
405 if ((ep
= malloc ((unsigned) i
)) == NULL
)
406 adios (NULL
, "out of memory");
407 for (dp
= nfs
, fp
= ep
; *dp
; dp
++) {
409 *fp
++ = '\\', *fp
++ = 'n';
412 if (*dp
== '"' || *dp
== '\\')
418 pop_command ("xtnd scan %d \"%s\"", width
, ep
);
419 printf ("%s\n", response
);
436 retr_action (char *rsp
, int flag
)
445 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
= mp
->hghmsg
+ 1)))
446 adios (NULL
, "unable to allocate folder storage");
448 cp
= getcpy (m_name (mp
->hghmsg
+ 1));
449 if ((fp
= fopen (cp
, "w+")) == NULL
)
450 adios (cp
, "unable to write");
451 chmod (cp
, m_gmprot ());
457 if (fstat (fileno (fp
), &st
) != NOTOK
&& st
.st_size
> 0) {
458 clear_msg_flags (mp
, msgnum
);
459 set_exists (mp
, msgnum
);
460 set_unseen (mp
, msgnum
);
461 mp
->msgflags
|= SEQMOD
;
464 advise (cp
, "write error on");
470 fclose (fp
), fp
= NULL
;
471 free (cp
), cp
= NULL
;
477 fprintf (fp
, "%s\n", rsp
);
486 char buf1
[BUFSIZ
], buf2
[BUFSIZ
], *vec
[9];
488 if (pop_fd (buf1
, sizeof(buf1
), buf2
, sizeof(buf2
)) == NOTOK
)
489 adios (NULL
, "%s", response
);
492 vec
[vecp
++] = r1bindex (mshproc
, '/');
494 switch (child_id
= fork ()) {
496 adios ("fork", "unable to");
499 vec
[vecp
++] = "-popread";
501 vec
[vecp
++] = "-popwrite";
503 vec
[vecp
++] = "-idname";
504 vec
[vecp
++] = mailname
;
505 vec
[vecp
++] = mailname
;
507 execvp (mshproc
, vec
);
508 fprintf (stderr
, "unable to exec ");
513 pidXwait (child_id
, mshproc
);
522 #include <mts/smtp/smtp.h>
525 dselect (struct direct
*d
)
529 if ((i
= strlen (d
->d_name
)) < sizeof "smtp"
530 || strncmp (d
->d_name
, "smtp", sizeof "smtp" - 1))
532 return ((i
-= (sizeof ".bulk" - 1)) > 0
533 && !strcmp (d
->d_name
+ i
, ".bulk"));
538 dcompar (struct direct
*d1
, struct direct
*d2
)
542 if (stat ((*d1
)->d_name
, &s1
) == NOTOK
)
544 if (stat ((*d2
)->d_name
, &s2
) == NOTOK
)
546 return ((int) (s1
.st_mtime
- s2
.st_mtime
));
555 struct direct
**namelist
;
557 if (chdir (bulksw
) == NOTOK
)
558 adios (bulksw
, "unable to change directory to");
560 if ((n
= scandir (".", &namelist
, dselect
, dcompar
)) == NOTOK
)
561 adios (bulksw
, "unable to scan directory");
564 for (i
= 0; i
< n
; i
++) {
565 register struct direct
*d
= namelist
[i
];
568 if (rp_isbad (retval
= sm_init (NULL
, host
, 1, 1, snoop
)))
569 adios (NULL
, "problem initializing server: %s",
575 switch (retval
= sm_bulk (d
->d_name
)) {
577 if (rp_isbad (retval
))
578 adios (NULL
, "problem delivering msg %s: %s",
579 d
->d_name
, rp_string (retval
));
584 advise (NULL
, "msg %s: %s", d
->d_name
, rp_string (retval
));
593 struct direct
**newlist
;
595 while ((l
= scandir (".", &newlist
, dselect
, dcompar
)) > OK
) {
598 for (j
= 0; j
< l
; j
++) {
599 register struct direct
*d
= newlist
[j
];
601 for (i
= 0; i
< n
; i
++)
602 if (strcmp (d
->d_name
, namelist
[i
]->d_name
) == 0)
605 switch (retval
= sm_bulk (d
->d_name
)) {
607 if (rp_isbad (retval
))
608 adios (NULL
, "problem delivering msg %s: %s",
609 d
->d_name
, rp_string (retval
));
614 advise (NULL
, "msg %s: %s", d
->d_name
,
623 for (i
= 0; i
< n
; i
++)
624 free ((char *) namelist
[i
]);
625 free ((char *) namelist
);
626 namelist
= newlist
, n
= l
;
634 if (sm
== OK
&& rp_isbad (retval
= sm_end (OK
)))
635 adios (NULL
, "problem finalizing server: %s", rp_string (retval
));
637 for (i
= 0; i
< n
; i
++)
638 free ((char *) namelist
[i
]);
639 free ((char *) namelist
);
641 free ((char *) namelist
);