]>
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 */
262 static struct swit popicmds
[] = {
305 printf ("(%s) ", invo_name
);
306 for (cp
= buffer
; (i
= getchar ()) != '\n'; ) {
315 if (cp
< buffer
+ sizeof buffer
- 2)
319 if (buffer
[0] == '\0')
321 if (buffer
[0] == '?') {
322 printf ("commands:\n");
323 print_sw (ALL
, popicmds
, "");
324 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name
);
328 if (cp
= strchr (buffer
, ' '))
330 switch (i
= smatch (buffer
, popicmds
)) {
332 ambigsw (buffer
, popicmds
);
335 printf ("%s unknown -- type \"?\" for help\n", buffer
);
349 pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "");
350 printf ("%s\n", response
);
356 if (pop_command ("%s%s", popicmds
[i
].sw
, cp
? cp
: "")
358 printf ("%s\n", response
);
361 switch (pop_multiline ()) {
363 strcpy (response
, ".");
366 printf ("%s\n", response
);
370 printf ("%s\n", response
);
380 advise (NULL
, "missing argument to %s", buffer
);
383 retr_action (NULL
, OK
);
384 pop_retr (atoi (++cp
), retr_action
);
385 retr_action (NULL
, DONE
);
386 printf ("%s\n", response
);
398 for (dp
= nfs
, i
= 0; *dp
; dp
++, i
++)
399 if (*dp
== '\\' || *dp
== '"' || *dp
== '\n')
402 if ((ep
= malloc ((unsigned) i
)) == NULL
)
403 adios (NULL
, "out of memory");
404 for (dp
= nfs
, fp
= ep
; *dp
; dp
++) {
406 *fp
++ = '\\', *fp
++ = 'n';
409 if (*dp
== '"' || *dp
== '\\')
415 pop_command ("xtnd scan %d \"%s\"", width
, ep
);
416 printf ("%s\n", response
);
433 retr_action (char *rsp
, int flag
)
442 if (!(mp
= folder_realloc (mp
, mp
->lowoff
, msgnum
= mp
->hghmsg
+ 1)))
443 adios (NULL
, "unable to allocate folder storage");
445 cp
= getcpy (m_name (mp
->hghmsg
+ 1));
446 if ((fp
= fopen (cp
, "w+")) == NULL
)
447 adios (cp
, "unable to write");
448 chmod (cp
, m_gmprot ());
454 if (fstat (fileno (fp
), &st
) != NOTOK
&& st
.st_size
> 0) {
455 clear_msg_flags (mp
, msgnum
);
456 set_exists (mp
, msgnum
);
457 set_unseen (mp
, msgnum
);
458 mp
->msgflags
|= SEQMOD
;
461 advise (cp
, "write error on");
467 fclose (fp
), fp
= NULL
;
468 free (cp
), cp
= NULL
;
474 fprintf (fp
, "%s\n", rsp
);
483 char buf1
[BUFSIZ
], buf2
[BUFSIZ
], *vec
[9];
485 if (pop_fd (buf1
, sizeof(buf1
), buf2
, sizeof(buf2
)) == NOTOK
)
486 adios (NULL
, "%s", response
);
489 vec
[vecp
++] = r1bindex (mshproc
, '/');
491 switch (child_id
= fork ()) {
493 adios ("fork", "unable to");
496 vec
[vecp
++] = "-popread";
498 vec
[vecp
++] = "-popwrite";
500 vec
[vecp
++] = "-idname";
501 vec
[vecp
++] = mailname
;
502 vec
[vecp
++] = mailname
;
504 execvp (mshproc
, vec
);
505 fprintf (stderr
, "unable to exec ");
510 pidXwait (child_id
, mshproc
);
518 #include <zotnet/mts/mts.h>
519 #include <mts/smtp/smtp.h>
522 dselect (struct direct
*d
)
526 if ((i
= strlen (d
->d_name
)) < sizeof "smtp"
527 || strncmp (d
->d_name
, "smtp", sizeof "smtp" - 1))
529 return ((i
-= (sizeof ".bulk" - 1)) > 0
530 && !strcmp (d
->d_name
+ i
, ".bulk"));
535 dcompar (struct direct
*d1
, struct direct
*d2
)
539 if (stat ((*d1
)->d_name
, &s1
) == NOTOK
)
541 if (stat ((*d2
)->d_name
, &s2
) == NOTOK
)
543 return ((int) (s1
.st_mtime
- s2
.st_mtime
));
552 struct direct
**namelist
;
554 if (chdir (bulksw
) == NOTOK
)
555 adios (bulksw
, "unable to change directory to");
557 if ((n
= scandir (".", &namelist
, dselect
, dcompar
)) == NOTOK
)
558 adios (bulksw
, "unable to scan directory");
561 for (i
= 0; i
< n
; i
++) {
562 register struct direct
*d
= namelist
[i
];
565 if (rp_isbad (retval
= sm_init (NULL
, host
, 1, 1, snoop
)))
566 adios (NULL
, "problem initializing server: %s",
572 switch (retval
= sm_bulk (d
->d_name
)) {
574 if (rp_isbad (retval
))
575 adios (NULL
, "problem delivering msg %s: %s",
576 d
->d_name
, rp_string (retval
));
581 advise (NULL
, "msg %s: %s", d
->d_name
, rp_string (retval
));
590 struct direct
**newlist
;
592 while ((l
= scandir (".", &newlist
, dselect
, dcompar
)) > OK
) {
595 for (j
= 0; j
< l
; j
++) {
596 register struct direct
*d
= newlist
[j
];
598 for (i
= 0; i
< n
; i
++)
599 if (strcmp (d
->d_name
, namelist
[i
]->d_name
) == 0)
602 switch (retval
= sm_bulk (d
->d_name
)) {
604 if (rp_isbad (retval
))
605 adios (NULL
, "problem delivering msg %s: %s",
606 d
->d_name
, rp_string (retval
));
611 advise (NULL
, "msg %s: %s", d
->d_name
,
620 for (i
= 0; i
< n
; i
++)
621 free ((char *) namelist
[i
]);
622 free ((char *) namelist
);
623 namelist
= newlist
, n
= l
;
631 if (sm
== OK
&& rp_isbad (retval
= sm_end (OK
)))
632 adios (NULL
, "problem finalizing server: %s", rp_string (retval
));
634 for (i
= 0; i
< n
; i
++)
635 free ((char *) namelist
[i
]);
636 free ((char *) namelist
);
638 free ((char *) namelist
);