5084b030a8493a6c346fef9ea8f2cd0aa2817bb3
[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 #include <h/utils.h>
14
15 static struct swit switches[] = {
16 #define VERSIONSW 0
17     { "version", 0 },
18 #define HELPSW  1
19     { "help", 0 },
20     { NULL, 0 }
21 };
22
23 /*
24  * Add space for message/sequence names
25  * by MAXMSGS at a time.
26  */
27 #define MAXMSGS 256
28
29
30 int
31 main(int argc, char **argv)
32 {
33     int i, maxmsgs, nummsgs;
34     char *cp, *maildir, *folder = NULL;
35     char **argp, **msgs;
36     char **arguments, buf[BUFSIZ];
37     struct msgs *mp;
38
39 #ifdef LOCALE
40     setlocale(LC_ALL, "");
41 #endif
42     invo_name = r1bindex (argv[0], '/');
43
44     /* read user profile/context */
45     context_read();
46
47     arguments = getarguments (invo_name, argc, argv, 1);
48     argp = arguments;
49
50     /*
51      * Allocate initial space to record message
52      * and sequence names
53      */
54     nummsgs = 0;
55     maxmsgs = MAXMSGS;
56     msgs = (char **) mh_xmalloc ((size_t) (maxmsgs * sizeof(*msgs)));
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 }