[bug #4302] errno is not always an extern int
[mmh] / uip / mhpath.c
1
2 /*
3  * mhpath.c -- print full pathnames of nmh messages and folders
4  *
5  * $Id$
6  *
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.
10  */
11
12 #include <h/mh.h>
13
14 static struct swit switches[] = {
15 #define VERSIONSW 0
16     { "version", 0 },
17 #define HELPSW  1
18     { "help", 0 },
19     { NULL, 0 }
20 };
21
22 /*
23  * Add space for message/sequence names
24  * by MAXMSGS at a time.
25  */
26 #define MAXMSGS 256
27
28
29 int
30 main(int argc, char **argv)
31 {
32     int i, maxmsgs, nummsgs;
33     char *cp, *maildir, *folder = NULL;
34     char **argp, **msgs;
35     char **arguments, buf[BUFSIZ];
36     struct msgs *mp;
37
38 #ifdef LOCALE
39     setlocale(LC_ALL, "");
40 #endif
41     invo_name = r1bindex (argv[0], '/');
42
43     /* read user profile/context */
44     context_read();
45
46     arguments = getarguments (invo_name, argc, argv, 1);
47     argp = arguments;
48
49     /*
50      * Allocate initial space to record message
51      * and sequence names
52      */
53     nummsgs = 0;
54     maxmsgs = MAXMSGS;
55     if (!(msgs = (char **) malloc ((size_t) (maxmsgs * sizeof(*msgs)))))
56         adios (NULL, "unable to allocate storage");
57
58     /*
59      * Parse arguments
60      */
61     while ((cp = *argp++)) {
62         if (*cp == '-') {
63             switch (smatch (++cp, switches)) {
64                 case AMBIGSW: 
65                     ambigsw (cp, switches);
66                     done (1);
67                 case UNKWNSW: 
68                     adios (NULL, "-%s unknown", cp);
69
70                 case HELPSW: 
71                     snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
72                         invo_name);
73                     print_help (buf, switches, 1);
74                     done (1);
75                 case VERSIONSW:
76                     print_version(invo_name);
77                     done (1);
78             }
79         }
80         if (*cp == '+' || *cp == '@') {
81             if (folder)
82                 adios (NULL, "only one folder at a time!");
83             else
84                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
85         } else {
86             /*
87              * if necessary, reallocate space for
88              * message/sequence names
89              */
90             if (nummsgs >= maxmsgs) {
91                 maxmsgs += MAXMSGS;
92                 if (!(msgs = (char **) realloc (msgs,
93                         (size_t) (maxmsgs * sizeof(*msgs)))))
94                     adios (NULL, "unable to reallocate msgs storage ");
95             }
96             msgs[nummsgs++] = cp;
97         }
98     }
99
100     if (!context_find ("path"))
101         free (path ("./", TFOLDER));
102
103     if (!folder)
104         folder = getfolder (1);
105     maildir = m_maildir (folder);
106
107     /* If no messages are given, print folder pathname */
108     if (!nummsgs) {
109         printf ("%s\n", maildir);
110         done (0);
111     }
112
113     if (chdir (maildir) == NOTOK)
114         adios (maildir, "unable to change directory to");
115
116     /* read folder and create message structure */
117     if (!(mp = folder_read (folder)))
118         adios (NULL, "unable to read folder %s", folder);
119
120     /*
121      * We need to make sure there is message status space
122      * for all the message numbers from 1 to "new" since
123      * mhpath can select empty slots.  If we are adding
124      * space at the end, we go ahead and add 10 slots.
125      */
126     if (mp->hghmsg >= mp->hghoff) {
127         if (!(mp = folder_realloc (mp, 1, mp->hghmsg + 10)))
128             adios (NULL, "unable to allocate folder storage");
129     } else if (mp->lowoff > 1) {
130         if (!(mp = folder_realloc (mp, 1, mp->hghoff)))
131             adios (NULL, "unable to allocate folder storage");
132     }
133
134     mp->msgflags |= ALLOW_NEW;  /* allow the "new" sequence */
135
136     /* parse all the message ranges/sequences and set SELECTED */
137     for (i = 0; i < nummsgs; i++)
138         if (!m_convert (mp, msgs[i]))
139             done (1);
140
141     seq_setprev (mp);   /* set the previous-sequence */
142
143     /* print the path of all selected messages */
144     for (i = mp->lowsel; i <= mp->hghsel; i++)
145         if (is_selected (mp, i))
146             printf ("%s/%s\n", mp->foldpath, m_name (i));
147
148     seq_save (mp);      /* synchronize message sequences */
149     context_save ();    /* save the context file         */
150     folder_free (mp);   /* free folder/message structure */
151     return done (0);
152 }