comparison uip/popi.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children a6481689f99c
comparison
equal deleted inserted replaced
-1:000000000000 0:bce86c4163a3
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