0
|
1 /* popi.c - POP initiator - for MPOP */
|
|
2 #ifndef lint
|
|
3 static char ident[] = "@(#)$Id$";
|
|
4 #endif lint
|
|
5
|
|
6 #include "../h/mh.h"
|
|
7 #include "../h/formatsbr.h"
|
|
8 #include "../h/scansbr.h"
|
|
9 #include <errno.h>
|
|
10 #include <stdio.h>
|
|
11 #include <sys/types.h>
|
|
12 #ifdef SMTP
|
|
13 #include "../h/local.h"
|
|
14 #else /* SMTP */
|
|
15 #include <sys/stat.h>
|
|
16 #endif /* SMTP */
|
|
17 #include "../zotnet/mts.h"
|
|
18 #ifdef SYS5DIR
|
|
19 #include <stdlib.h>
|
|
20 #endif
|
|
21
|
|
22 /* */
|
|
23
|
|
24 #ifndef RPOP
|
|
25 #define RPOPminc(a) (a)
|
|
26 #else
|
|
27 #define RPOPminc(a) 0
|
|
28 #endif
|
|
29
|
|
30 #ifndef APOP
|
|
31 #define APOPminc(a) (a)
|
|
32 #else
|
|
33 #define APOPminc(a) 0
|
|
34 #endif
|
|
35
|
|
36 #if !defined(BPOP) || defined(NNTP)
|
|
37 #define BPOPminc(a) (a)
|
|
38 #else
|
|
39 #define BPOPminc(a) 0
|
|
40 #endif
|
|
41
|
|
42 #ifndef SMTP
|
|
43 #define BULKminc(a) (a)
|
|
44 #else
|
|
45 #define BULKminc(a) 0
|
|
46 #endif
|
|
47
|
|
48 static struct swit switches[] = {
|
|
49 #define APOPSW 0
|
|
50 "apop", APOPminc (-4),
|
|
51 #define NAPOPSW 1
|
|
52 "noapop", APOPminc (-6),
|
|
53
|
|
54 #define AUTOSW 2
|
|
55 "auto", BPOPminc(-4),
|
|
56 #define NAUTOSW 3
|
|
57 "noauto", BPOPminc(-6),
|
|
58
|
|
59 #define BULKSW 4
|
|
60 "bulk directory", BULKminc(-4),
|
|
61
|
|
62 #define FORMSW 5
|
|
63 "form formatfile", 0,
|
|
64
|
|
65 #define FMTSW 6
|
|
66 "format string", 5,
|
|
67
|
|
68 #define HOSTSW 7
|
|
69 "host host", 0,
|
|
70
|
|
71 #define PROGSW 8
|
|
72 "mshproc program", 0,
|
|
73
|
|
74 #define RPOPSW 9
|
|
75 "rpop", RPOPminc (-4),
|
|
76 #define NRPOPSW 10
|
|
77 "norpop", RPOPminc (-6),
|
|
78
|
|
79 #define USERSW 11
|
|
80 "user user", 0,
|
|
81
|
|
82 #define WIDSW 12
|
|
83 "width columns", 0,
|
|
84
|
|
85 #define HELPSW 13
|
|
86 "help", 4,
|
|
87
|
|
88 NULL, 0
|
|
89 };
|
|
90
|
|
91 /* */
|
|
92
|
|
93 static char *bulksw = NULLCP;
|
|
94 static int snoop = 0;
|
|
95 static int width = 0;
|
|
96
|
|
97 static char mailname[BUFSIZ];
|
|
98
|
|
99 static char *nfs = NULL;
|
|
100
|
|
101 static struct msgs *mp;
|
|
102
|
|
103 extern int errno;
|
|
104
|
|
105 extern char response[];
|
|
106
|
|
107 static popi(), retr_action();
|
|
108 #if defined(BPOP) && !defined(NNTP)
|
|
109 static msh();
|
|
110 #endif
|
|
111 #ifdef SMTP
|
|
112 static do_bulk();
|
|
113 #endif
|
|
114
|
|
115 /* */
|
|
116
|
|
117 /* ARGSUSED */
|
|
118
|
|
119 main (argc, argv)
|
|
120 int argc;
|
|
121 char *argv[];
|
|
122 {
|
|
123 int autosw = 1,
|
|
124 noisy = 1,
|
|
125 rpop;
|
|
126 char *cp,
|
|
127 *maildir,
|
|
128 *folder = NULL,
|
|
129 *form = NULL,
|
|
130 *format = NULL,
|
|
131 *host = NULL,
|
|
132 *user = NULL,
|
|
133 *pass = NULL,
|
|
134 buf[100],
|
|
135 **ap,
|
|
136 **argp,
|
|
137 *arguments[MAXARGS];
|
|
138 struct stat st;
|
|
139
|
|
140 invo_name = r1bindex (argv[0], '/');
|
|
141 mts_init (invo_name);
|
|
142 if (pophost && *pophost)
|
|
143 host = pophost;
|
|
144 if ((cp = getenv ("MHPOPDEBUG")) && *cp)
|
|
145 snoop++;
|
|
146 if ((cp = m_find (invo_name)) != NULL) {
|
|
147 ap = brkstring (cp = getcpy (cp), " ", "\n");
|
|
148 ap = copyip (ap, arguments);
|
|
149 }
|
|
150 else
|
|
151 ap = arguments;
|
|
152 (void) copyip (argv + 1, ap);
|
|
153 argp = arguments;
|
|
154
|
|
155 rpop = getuid () && !geteuid ();
|
|
156
|
|
157 /* */
|
|
158
|
|
159 while (cp = *argp++) {
|
|
160 if (*cp == '-')
|
|
161 switch (smatch (++cp, switches)) {
|
|
162 case AMBIGSW:
|
|
163 ambigsw (cp, switches);
|
|
164 done (1);
|
|
165 case UNKWNSW:
|
|
166 adios (NULLCP, "-%s unknown", cp);
|
|
167 case HELPSW:
|
|
168 (void) sprintf (buf, "%s [+folder] [switches]", invo_name);
|
|
169 help (buf, switches);
|
|
170 done (1);
|
|
171
|
|
172 case AUTOSW:
|
|
173 autosw = 1;
|
|
174 continue;
|
|
175 case NAUTOSW:
|
|
176 autosw = 0;
|
|
177 continue;
|
|
178
|
|
179 case BULKSW:
|
|
180 if (!(bulksw = *argp++) || *bulksw == '-')
|
|
181 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
182 continue;
|
|
183
|
|
184 case FORMSW:
|
|
185 if (!(form = *argp++) || *form == '-')
|
|
186 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
187 format = NULL;
|
|
188 continue;
|
|
189 case FMTSW:
|
|
190 if (!(format = *argp++) || *format == '-')
|
|
191 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
192 form = NULL;
|
|
193 continue;
|
|
194
|
|
195 case WIDSW:
|
|
196 if (!(cp = *argp++) || *cp == '-')
|
|
197 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
198 width = atoi (cp);
|
|
199 continue;
|
|
200
|
|
201 case HOSTSW:
|
|
202 if (!(host = *argp++) || *host == '-')
|
|
203 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
204 continue;
|
|
205 case USERSW:
|
|
206 if (!(user = *argp++) || *user == '-')
|
|
207 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
208 continue;
|
|
209
|
|
210 case APOPSW:
|
|
211 rpop = -1;
|
|
212 continue;
|
|
213 case RPOPSW:
|
|
214 rpop = 1;
|
|
215 continue;
|
|
216 case NAPOPSW:
|
|
217 case NRPOPSW:
|
|
218 rpop = 0;
|
|
219 continue;
|
|
220
|
|
221 case PROGSW:
|
|
222 if (!(mshproc = *argp++) || *mshproc == '-')
|
|
223 adios (NULLCP, "missing argument to %s", argp[-2]);
|
|
224 continue;
|
|
225 }
|
|
226 if (*cp == '+' || *cp == '@') {
|
|
227 if (folder)
|
|
228 adios (NULLCP, "only one folder at a time!");
|
|
229 else
|
|
230 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
|
|
231 }
|
|
232 else
|
|
233 adios (NULLCP, "usage: %s [+folder] [switches]", invo_name);
|
|
234 }
|
|
235
|
|
236 /* */
|
|
237
|
|
238 if (!host)
|
|
239 adios (NULLCP, "usage: %s -host \"host\"", invo_name);
|
|
240
|
|
241 #ifdef SMTP
|
|
242 if (bulksw)
|
|
243 do_bulk (host);
|
|
244 #endif
|
|
245
|
|
246 if (user == NULL)
|
|
247 user = getusr ();
|
|
248 if (rpop > 0)
|
|
249 pass = getusr ();
|
|
250 else {
|
|
251 (void) setuid (getuid ());
|
|
252 ruserpass (host, &user, &pass);
|
|
253 }
|
|
254 (void) sprintf (mailname, "PO box for %s@%s", user, host);
|
|
255
|
|
256 if (pop_init (host, user, pass, snoop, rpop) == NOTOK)
|
|
257 adios (NULLCP, "%s", response);
|
|
258 if (rpop > 0)
|
|
259 (void) setuid (getuid ());
|
|
260
|
|
261 nfs = new_fs (form, format, FORMAT);
|
|
262
|
|
263 if (!m_find ("path"))
|
|
264 free (path ("./", TFOLDER));
|
|
265 if (!folder && !(folder = m_find (inbox)))
|
|
266 folder = defalt;
|
|
267 maildir = m_maildir (folder);
|
|
268
|
|
269 if (stat (maildir, &st) == NOTOK) {
|
|
270 if (errno != ENOENT)
|
|
271 adios (maildir, "error on folder");
|
|
272 cp = concat ("Create folder \"", maildir, "\"? ", NULLCP);
|
|
273 if (noisy && !getanswer (cp))
|
|
274 done (1);
|
|
275 free (cp);
|
|
276 if (!makedir (maildir))
|
|
277 adios (NULLCP, "unable to create folder %s", maildir);
|
|
278 }
|
|
279
|
|
280 if (chdir (maildir) == NOTOK)
|
|
281 adios (maildir, "unable to change directory to");
|
|
282 if (!(mp = m_gmsg (folder)))
|
|
283 adios (NULLCP, "unable to read folder %s", folder);
|
|
284
|
|
285 #if defined(BPOP) && !defined(NNTP)
|
|
286 if (autosw)
|
|
287 msh ();
|
|
288 else
|
|
289 #endif
|
|
290 popi ();
|
|
291
|
|
292 (void) pop_quit ();
|
|
293
|
|
294 m_replace (pfolder, folder);
|
|
295 m_setvis (mp, 0);
|
|
296 m_sync (mp);
|
|
297 m_update ();
|
|
298
|
|
299 done (0);
|
|
300
|
|
301 /* NOTREACHED */
|
|
302 }
|
|
303
|
|
304 /* */
|
|
305
|
|
306 static struct swit popicmds[] = {
|
|
307 #define DELECMD 0
|
|
308 "dele", 0,
|
|
309 #define LASTCMD 1
|
|
310 "last", 0,
|
|
311 #define LISTCMD 2
|
|
312 "list", 0,
|
|
313 #define NOOPCMD 3
|
|
314 "noop", 0,
|
|
315 #define QUITCMD 4
|
|
316 "quit", 0,
|
|
317 #define RETRCMD 5
|
|
318 "retr", 0,
|
|
319 #define RSETCMD 6
|
|
320 "rset", 0,
|
|
321 #define SCANCMD 7
|
|
322 "scan", 0,
|
|
323 #define STATCMD 8
|
|
324 "stat", 0,
|
|
325 #define TOPCMD 9
|
|
326 "top", 0,
|
|
327 #if defined(BPOP) && !defined(NNTP)
|
|
328 #define MSHCMD 10
|
|
329 "msh", 0,
|
|
330 #endif
|
|
331
|
|
332 NULL, 0
|
|
333 };
|
|
334
|
|
335 /* */
|
|
336
|
|
337 static popi ()
|
|
338 {
|
|
339 int eof;
|
|
340
|
|
341 eof = 0;
|
|
342 for (;;) {
|
|
343 int i;
|
|
344 register char *cp;
|
|
345 char buffer[BUFSIZ];
|
|
346
|
|
347 if (eof)
|
|
348 return;
|
|
349
|
|
350 printf ("(%s) ", invo_name);
|
|
351 for (cp = buffer; (i = getchar ()) != '\n'; ) {
|
|
352 if (i == EOF) {
|
|
353 (void) putchar ('\n');
|
|
354 if (cp == buffer)
|
|
355 return;
|
|
356 eof = 1;
|
|
357 break;
|
|
358 }
|
|
359
|
|
360 if (cp < buffer + sizeof buffer - 2)
|
|
361 *cp++ = i;
|
|
362 }
|
|
363 *cp = '\0';
|
|
364 if (buffer[0] == '\0')
|
|
365 continue;
|
|
366 if (buffer[0] == '?') {
|
|
367 printf ("commands:\n");
|
|
368 printsw (ALL, popicmds, "");
|
|
369 printf ("type CTRL-D or use \"quit\" to leave %s\n", invo_name);
|
|
370 continue;
|
|
371 }
|
|
372
|
|
373 if (cp = index (buffer, ' '))
|
|
374 *cp = '\0';
|
|
375 switch (i = smatch (buffer, popicmds)) {
|
|
376 case AMBIGSW:
|
|
377 ambigsw (buffer, popicmds);
|
|
378 continue;
|
|
379 case UNKWNSW:
|
|
380 printf ("%s unknown -- type \"?\" for help\n", buffer);
|
|
381 continue;
|
|
382
|
|
383 case QUITCMD:
|
|
384 return;
|
|
385
|
|
386 case STATCMD:
|
|
387 case DELECMD:
|
|
388 case NOOPCMD:
|
|
389 case LASTCMD:
|
|
390 case RSETCMD:
|
|
391 case TOPCMD:
|
|
392 if (cp)
|
|
393 *cp = ' ';
|
|
394 (void) pop_command ("%s%s", popicmds[i].sw, cp ? cp : "");
|
|
395 printf ("%s\n", response);
|
|
396 break;
|
|
397
|
|
398 case LISTCMD:
|
|
399 if (cp)
|
|
400 *cp = ' ';
|
|
401 if (pop_command ("%s%s", popicmds[i].sw, cp ? cp : "")
|
|
402 == OK) {
|
|
403 printf ("%s\n", response);
|
|
404 if (!cp)
|
|
405 for (;;) {
|
|
406 switch (pop_multiline ()) {
|
|
407 case DONE:
|
|
408 (void) strcpy (response, ".");
|
|
409 /* and fall... */
|
|
410 case NOTOK:
|
|
411 printf ("%s\n", response);
|
|
412 break;
|
|
413
|
|
414 case OK:
|
|
415 printf ("%s\n", response);
|
|
416 continue;
|
|
417 }
|
|
418 break;
|
|
419 }
|
|
420 }
|
|
421 break;
|
|
422
|
|
423 case RETRCMD:
|
|
424 if (!cp) {
|
|
425 advise (NULLCP, "missing argument to %s", buffer);
|
|
426 break;
|
|
427 }
|
|
428 retr_action (NULLCP, OK);
|
|
429 (void) pop_retr (atoi (++cp), retr_action);
|
|
430 retr_action (NULLCP, DONE);
|
|
431 printf ("%s\n", response);
|
|
432 break;
|
|
433
|
|
434 case SCANCMD:
|
|
435 {
|
|
436 char *dp,
|
|
437 *ep,
|
|
438 *fp;
|
|
439
|
|
440 if (width == 0)
|
|
441 width = sc_width ();
|
|
442
|
|
443 for (dp = nfs, i = 0; *dp; dp++, i++)
|
|
444 if (*dp == '\\' || *dp == '"' || *dp == '\n')
|
|
445 i++;
|
|
446 i++;
|
|
447 if ((ep = malloc ((unsigned) i)) == NULL)
|
|
448 adios (NULLCP, "out of memory");
|
|
449 for (dp = nfs, fp = ep; *dp; dp++) {
|
|
450 if (*dp == '\n') {
|
|
451 *fp++ = '\\', *fp++ = 'n';
|
|
452 continue;
|
|
453 }
|
|
454 if (*dp == '"' || *dp == '\\')
|
|
455 *fp++ = '\\';
|
|
456 *fp++ = *dp;
|
|
457 }
|
|
458 *fp = '\0';
|
|
459
|
|
460 (void) pop_command ("xtnd scan %d \"%s\"", width, ep);
|
|
461 printf ("%s\n", response);
|
|
462
|
|
463 free (ep);
|
|
464 }
|
|
465 break;
|
|
466
|
|
467 #if defined(BPOP) && !defined(NNTP)
|
|
468 case MSHCMD:
|
|
469 msh ();
|
|
470 break;
|
|
471 #endif
|
|
472 }
|
|
473 }
|
|
474 }
|
|
475
|
|
476 /* */
|
|
477
|
|
478 static int retr_action (rsp, flag)
|
|
479 char *rsp;
|
|
480 int flag;
|
|
481 {
|
|
482 static FILE *fp;
|
|
483
|
|
484 if (rsp == NULL) {
|
|
485 static int msgnum;
|
|
486 static char *cp;
|
|
487
|
|
488 if (flag == OK) {
|
|
489 if ((mp = m_remsg (mp, 0, msgnum = mp -> hghmsg + 1)) == NULL)
|
|
490 adios (NULLCP, "unable to allocate folder storage");
|
|
491
|
|
492 cp = getcpy (m_name (mp -> hghmsg + 1));
|
|
493 if ((fp = fopen (cp, "w+")) == NULL)
|
|
494 adios (cp, "unable to write");
|
|
495 (void) chmod (cp, m_gmprot ());
|
|
496 }
|
|
497 else {
|
|
498 struct stat st;
|
|
499
|
|
500 (void) fflush (fp);
|
|
501 if (fstat (fileno (fp), &st) != NOTOK && st.st_size > 0) {
|
|
502 mp -> msgstats[msgnum] = EXISTS | UNSEEN;
|
|
503 mp -> msgflags |= SEQMOD;
|
|
504
|
|
505 if (ferror (fp))
|
|
506 advise (cp, "write error on");
|
|
507 mp -> hghmsg = msgnum;
|
|
508 }
|
|
509 else
|
|
510 (void) unlink (cp);
|
|
511
|
|
512 (void) fclose (fp), fp = NULL;
|
|
513 free (cp), cp = NULL;
|
|
514 }
|
|
515
|
|
516 return;
|
|
517 }
|
|
518
|
|
519 fprintf (fp, "%s\n", rsp);
|
|
520 }
|
|
521
|
|
522 /* */
|
|
523
|
|
524 #if defined(BPOP) && !defined(NNTP)
|
|
525 static msh ()
|
|
526 {
|
|
527 int child_id,
|
|
528 vecp;
|
|
529 char buf1[BUFSIZ],
|
|
530 buf2[BUFSIZ],
|
|
531 *vec[9];
|
|
532
|
|
533 if (pop_fd (buf1, buf2) == NOTOK)
|
|
534 adios (NULLCP, "%s", response);
|
|
535
|
|
536 vecp = 0;
|
|
537 vec[vecp++] = r1bindex (mshproc, '/');
|
|
538
|
|
539 switch (child_id = fork ()) {
|
|
540 case NOTOK:
|
|
541 adios ("fork", "unable to");
|
|
542
|
|
543 case OK:
|
|
544 vec[vecp++] = "-popread";
|
|
545 vec[vecp++] = buf1;
|
|
546 vec[vecp++] = "-popwrite";
|
|
547 vec[vecp++] = buf2;
|
|
548 vec[vecp++] = "-idname";
|
|
549 vec[vecp++] = mailname;
|
|
550 vec[vecp++] = mailname;
|
|
551 vec[vecp] = NULL;
|
|
552 (void) execvp (mshproc, vec);
|
|
553 fprintf (stderr, "unable to exec ");
|
|
554 perror (mshproc);
|
|
555 _exit (-1);
|
|
556
|
|
557 default:
|
|
558 (void) pidXwait (child_id, mshproc);
|
|
559 break;
|
|
560 }
|
|
561 }
|
|
562 #endif
|
|
563
|
|
564 /* */
|
|
565
|
|
566 #ifdef SMTP
|
|
567 #include "../zotnet/mts.h"
|
|
568 #include "../mts/sendmail/smail.h"
|
|
569
|
|
570
|
|
571 static int dselect (d)
|
|
572 #ifdef SYS5DIR
|
|
573 register struct dirent *d;
|
|
574 #else
|
|
575 register struct direct *d;
|
|
576 #endif
|
|
577 {
|
|
578 int i;
|
|
579
|
|
580 if ((i = strlen (d -> d_name)) < sizeof "smtp"
|
|
581 || strncmp (d -> d_name, "smtp", sizeof "smtp" - 1))
|
|
582 return 0;
|
|
583 return ((i -= (sizeof ".bulk" - 1)) > 0
|
|
584 && !strcmp (d -> d_name + i, ".bulk"));
|
|
585 }
|
|
586
|
|
587
|
|
588 static int dcompar (d1, d2)
|
|
589 #ifdef SYS5DIR
|
|
590 struct dirent **d1,
|
|
591 **d2;
|
|
592 #else
|
|
593 struct direct **d1,
|
|
594 **d2;
|
|
595 #endif
|
|
596 {
|
|
597 struct stat s1,
|
|
598 s2;
|
|
599
|
|
600 if (stat ((*d1) -> d_name, &s1) == NOTOK)
|
|
601 return 1;
|
|
602 if (stat ((*d2) -> d_name, &s2) == NOTOK)
|
|
603 return -1;
|
|
604 return ((int) (s1.st_mtime - s2.st_mtime));
|
|
605 }
|
|
606
|
|
607
|
|
608 static do_bulk (host)
|
|
609 char *host;
|
|
610 {
|
|
611 register int i;
|
|
612 int n,
|
|
613 retval,
|
|
614 sm;
|
|
615 #ifdef SYS5DIR
|
|
616 struct dirent **namelist;
|
|
617 #else
|
|
618 struct direct **namelist;
|
|
619 #endif
|
|
620
|
|
621 if (chdir (bulksw) == NOTOK)
|
|
622 adios (bulksw, "unable to change directory to");
|
|
623
|
|
624 if ((n = scandir (".", &namelist, dselect, dcompar)) == NOTOK)
|
|
625 adios (bulksw, "unable to scan directory");
|
|
626
|
|
627 sm = NOTOK;
|
|
628 for (i = 0; i < n; i++) {
|
|
629 #ifdef SYS5DIR
|
|
630 register struct dirent *d = namelist[i];
|
|
631 #else
|
|
632 register struct direct *d = namelist[i];
|
|
633 #endif
|
|
634
|
|
635 if (sm == NOTOK) {
|
|
636 if (rp_isbad (retval = sm_init (NULLCP, host, 1, 1, snoop)))
|
|
637 adios (NULLCP, "problem initializing server: %s",
|
|
638 rp_string (retval));
|
|
639 else
|
|
640 sm = OK;
|
|
641 }
|
|
642
|
|
643 switch (retval = sm_bulk (d -> d_name)) {
|
|
644 default:
|
|
645 if (rp_isbad (retval))
|
|
646 adios (NULLCP, "problem delivering msg %s: %s",
|
|
647 d -> d_name, rp_string (retval));
|
|
648 /* else fall... */
|
|
649 case RP_OK:
|
|
650 case RP_NO:
|
|
651 case RP_NDEL:
|
|
652 advise (NULLCP, "msg %s: %s", d -> d_name, rp_string (retval));
|
|
653 break;
|
|
654 }
|
|
655 }
|
|
656
|
|
657 if (sm == OK) {
|
|
658 register int j;
|
|
659 int l,
|
|
660 m;
|
|
661 #ifdef SYS5DIR
|
|
662 struct dirent **newlist;
|
|
663 #else
|
|
664 struct direct **newlist;
|
|
665 #endif
|
|
666
|
|
667 while ((l = scandir (".", &newlist, dselect, dcompar)) > OK) {
|
|
668 m = 0;
|
|
669
|
|
670 for (j = 0; j < l; j++) {
|
|
671 #ifdef SYS5DIR
|
|
672 register struct dirent *d = newlist[j];
|
|
673 #else
|
|
674 register struct direct *d = newlist[j];
|
|
675 #endif
|
|
676
|
|
677 for (i = 0; i < n; i++)
|
|
678 if (strcmp (d -> d_name, namelist[i] -> d_name) == 0)
|
|
679 break;
|
|
680 if (i >= n) {
|
|
681 switch (retval = sm_bulk (d -> d_name)) {
|
|
682 default:
|
|
683 if (rp_isbad (retval))
|
|
684 adios (NULLCP, "problem delivering msg %s: %s",
|
|
685 d -> d_name, rp_string (retval));
|
|
686 /* else fall... */
|
|
687 case RP_OK:
|
|
688 case RP_NO:
|
|
689 case RP_NDEL:
|
|
690 advise (NULLCP, "msg %s: %s", d -> d_name,
|
|
691 rp_string (retval));
|
|
692 break;
|
|
693 }
|
|
694
|
|
695 m = 1;
|
|
696 }
|
|
697 }
|
|
698
|
|
699 for (i = 0; i < n; i++)
|
|
700 free ((char *) namelist[i]);
|
|
701 free ((char *) namelist);
|
|
702 namelist = newlist, n = l;
|
|
703
|
|
704 if (!m)
|
|
705 break;
|
|
706 newlist = NULL;
|
|
707 }
|
|
708 }
|
|
709
|
|
710 if (sm == OK && rp_isbad (retval = sm_end (OK)))
|
|
711 adios (NULLCP, "problem finalizing server: %s", rp_string (retval));
|
|
712
|
|
713 for (i = 0; i < n; i++)
|
|
714 free ((char *) namelist[i]);
|
|
715 free ((char *) namelist);
|
|
716
|
|
717 free ((char *) namelist);
|
|
718
|
|
719 done (0);
|
|
720 }
|
|
721 #endif
|
|
722 #if defined(SYS5DIR) && !defined(BSD42) && !defined(hpux) && !defined(sgi) && !defined(linux)
|
|
723 /*
|
|
724 * Copyright (c) 1983 Regents of the University of California.
|
|
725 * All rights reserved.
|
|
726 *
|
|
727 * Redistribution and use in source and binary forms, with or without
|
|
728 * modification, are permitted provided that the following conditions
|
|
729 * are met:
|
|
730 * 1. Redistributions of source code must retain the above copyright
|
|
731 * notice, this list of conditions and the following disclaimer.
|
|
732 * 2. Redistributions in binary form must reproduce the above copyright
|
|
733 * notice, this list of conditions and the following disclaimer in the
|
|
734 * documentation and/or other materials provided with the distribution.
|
|
735 * 3. All advertising materials mentioning features or use of this software
|
|
736 * must display the following acknowledgement:
|
|
737 * This product includes software developed by the University of
|
|
738 * California, Berkeley and its contributors.
|
|
739 * 4. Neither the name of the University nor the names of its contributors
|
|
740 * may be used to endorse or promote products derived from this software
|
|
741 * without specific prior written permission.
|
|
742 *
|
|
743 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
744 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
745 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
746 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
747 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
748 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
749 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
750 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
751 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
752 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
753 * SUCH DAMAGE.
|
|
754 */
|
|
755 #if defined(LIBC_SCCS) && !defined(lint)
|
|
756 static char sccsid[] = "@(#)scandir.c 5.10 (Berkeley) 2/23/91";
|
|
757 #endif /* LIBC_SCCS and not lint */
|
|
758 /*
|
|
759 * Scan the directory dirname calling select to make a list of selected
|
|
760 * directory entries then sort using qsort and compare routine dcomp.
|
|
761 * Returns the number of entries and a pointer to a list of pointers to
|
|
762 * struct dirent (through namelist). Returns -1 if there were any errors.
|
|
763 */
|
|
764 /*
|
|
765 * This code modified by Ted Nolan to take Solaris dirent structures
|
|
766 * and mollify gcc -traditional. In general, everything from BSD that
|
|
767 * didn't work is "ifdef notdef" ed out
|
|
768 *
|
|
769 * 3 Feb 94
|
|
770 */
|
|
771 #include <sys/types.h>
|
|
772 #include <sys/stat.h>
|
|
773 #include <dirent.h>
|
|
774 /* #include <stdlib.h> */
|
|
775 #include <string.h>
|
|
776 /*
|
|
777 * The DIRSIZ macro gives the minimum record length which will hold
|
|
778 * the directory entry. This requires the amount of space in struct dirent
|
|
779 * without the d_name field, plus enough space for the name with a terminating
|
|
780 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
|
|
781 */
|
|
782 #undef DIRSIZ
|
|
783 #ifdef notdef
|
|
784 #define DIRSIZ(dp) \
|
|
785 ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
|
|
786 #else
|
|
787 #define DIRSIZ(dp) \
|
|
788 ((sizeof (struct dirent) - (MAXNAMLEN+1)) + ((strlen(dp->d_name)+1 + 3) &~ 3))
|
|
789 #endif
|
|
790 int
|
|
791 scandir(dirname, namelist, select, dcomp)
|
|
792 #ifdef notdef
|
|
793 const char *dirname;
|
|
794 #else
|
|
795 char *dirname;
|
|
796 #endif
|
|
797 struct dirent ***namelist;
|
|
798 #ifdef notdef
|
|
799 int (*select) __P((struct dirent *));
|
|
800 int (*dcomp) __P((const void *, const void *));
|
|
801 #else
|
|
802 int (*select)();
|
|
803 int (*dcomp)();
|
|
804 #endif
|
|
805 {
|
|
806 register struct dirent *d, *p, **names;
|
|
807 register size_t nitems;
|
|
808 struct stat stb;
|
|
809 long arraysz;
|
|
810 DIR *dirp;
|
|
811 if ((dirp = opendir(dirname)) == NULL)
|
|
812 return(-1);
|
|
813 if (stat(dirname, &stb) < 0)
|
|
814 return(-1);
|
|
815 /*
|
|
816 * estimate the array size by taking the size of the directory file
|
|
817 * and dividing it by a multiple of the minimum size entry.
|
|
818 */
|
|
819 arraysz = (stb.st_size / 24);
|
|
820 names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
|
|
821 if (names == NULL)
|
|
822 return(-1);
|
|
823 nitems = 0;
|
|
824 while ((d = readdir(dirp)) != NULL) {
|
|
825 if (select != NULL && !(*select)(d))
|
|
826 continue; /* just selected names */
|
|
827 /*
|
|
828 * Make a minimum size copy of the data
|
|
829 */
|
|
830 p = (struct dirent *)malloc(DIRSIZ(d));
|
|
831 if (p == NULL)
|
|
832 return(-1);
|
|
833 p->d_ino = d->d_ino;
|
|
834 p->d_reclen = d->d_reclen;
|
|
835 #ifdef notdef
|
|
836 p->d_namlen = d->d_namlen;
|
|
837 bcopy(d->d_name, p->d_name, p->d_namlen + 1);
|
|
838 #else
|
|
839 bcopy(d->d_name, p->d_name, strlen(p->d_name) + 1);
|
|
840 #endif
|
|
841 /*
|
|
842 * Check to make sure the array has space left and
|
|
843 * realloc the maximum size.
|
|
844 */
|
|
845 if (++nitems >= arraysz) {
|
|
846 if (stat(dirname, &stb) < 0)
|
|
847 return(-1); /* just might have grown */
|
|
848 arraysz = stb.st_size / 12;
|
|
849 names = (struct dirent **)realloc((char *)names,
|
|
850 arraysz * sizeof(struct dirent *));
|
|
851 if (names == NULL)
|
|
852 return(-1);
|
|
853 }
|
|
854 names[nitems-1] = p;
|
|
855 }
|
|
856 closedir(dirp);
|
|
857 if (nitems && dcomp != NULL)
|
|
858 qsort(names, nitems, sizeof(struct dirent *), dcomp);
|
|
859 *namelist = names;
|
|
860 return(nitems);
|
|
861 }
|
|
862 /*
|
|
863 * Alphabetic order comparison routine for those who want it.
|
|
864 */
|
|
865 int
|
|
866 alphasort(d1, d2)
|
|
867 #ifdef notdef
|
|
868 const void *d1;
|
|
869 const void *d2;
|
|
870 #else
|
|
871 char *d1;
|
|
872 char *d2;
|
|
873 #endif /* notdef */
|
|
874 {
|
|
875 return(strcmp((*(struct dirent **)d1)->d_name,
|
|
876 (*(struct dirent **)d2)->d_name));
|
|
877 }
|
|
878 #endif
|