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