]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/mhpath.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / mhpath.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "../mh.h"
9 #include <stdio.h>
10 #include <strings.h>
11
12
13 struct msgs *mp;
14 extern char _sobuf[];
15
16 struct swit switches[] = {
17 "all", -3, /* 0 */
18 "help", 4, /* 1 */
19 0, 0
20 };
21
22 /*ARGSUSED*/
23 main(argc, argv)
24 int argc;
25 char *argv[];
26 {
27 char *cp;
28 char *mhnam();
29
30 if(!(cp = mhnam(&argv[1])))
31 done(1);
32 printf("%s\n", cp); /* Expanded message list */
33 done(0);
34 }
35
36 char *
37 mhnam(args)
38 char **args;
39 {
40 int j;
41 static char *string;
42 char buf[100];
43 char *folder, *maildir, *msgs[100];
44 register int msgnum;
45 register char *cp;
46 int msgp;
47 char *arguments[50], **argp;
48
49 setbuf(stdout, _sobuf);
50
51 folder = (char *) 0;
52 msgp = 0;
53 VOID copyip(args, arguments);
54 argp = arguments;
55 while(cp = *argp++) {
56 if(*cp == '-')
57 switch(smatch(++cp, switches)) {
58 case -2:ambigsw(cp, switches); /* ambiguous */
59 return(0);
60 /* unknown */
61 case -1:fprintf(stderr, "mhnam: -%s unknown\n", cp);
62 return(0);
63 /* -all */
64 case 0: fprintf(stderr, "\"-all\" changed to \"all\"\n");
65 return(0);
66 case 1: help("mhnam [+folder] [msgs] [switches]", switches);
67 return(0);
68 }
69 if(*cp == '+') {
70 if(folder) {
71 fprintf(stderr, "Only one folder at a time.\n");
72 return(0);
73 } else
74 folder = path(cp+1, TFOLDER);
75 } else
76 msgs[msgp++] = cp;
77 }
78 if(!m_find("path")) free(path("./", TFOLDER));
79
80 /* Mhpath defaults to the folder name */
81 /*** if(!msgp)
82 *** msgs[msgp++] = "cur";
83 ***/
84
85 if(!folder)
86 folder = m_getfolder();
87 maildir = m_maildir(folder);
88
89
90 if(!msgp)
91 return(maildir);
92
93
94 if(chdir(maildir) < 0) {
95 fprintf(stderr, "Can't chdir to: ");
96 perror(maildir);
97 return(0);
98 }
99
100 if(!(mp = m_gmsg(folder))) {
101 fprintf(stderr, "Can't read folder!?\n");
102 return(0);
103 }
104 /* Need to accomodate MAXFOLDER messages instead of mp->hghmsg */
105 if( (char *) (mp = (struct msgs *)
106 realloc((char *) mp, (unsigned)(sizeof *mp + MAXFOLDER + 1 + 2)))
107 == (char *) 0)
108 return(0);
109
110 /* Clear the newly allocated space */
111 for(j = mp->hghmsg + 1; j <= MAXFOLDER; j++)
112 mp->msgstats[j] = 0;
113
114 /* Mhpath permits empty folders */
115 /*** if(mp->hghmsg == 0) {
116 *** fprintf(stderr, "No messages in \"%s\".\n", folder);
117 *** return(0);
118 *** }
119 ***/
120
121 if(msgp)
122 for(msgnum = 0; msgnum < msgp; msgnum++)
123 if(!convert(msgs[msgnum]))
124 return(0);
125 if(mp->numsel == 0) {
126 fprintf(stderr, "mhnam: Never get here. \n");
127 return(0);
128 }
129 if(mp->numsel > MAXARGS-2) {
130 fprintf(stderr, "mhnam: more than %d messages \n", MAXARGS-2);
131 return(0);
132 }
133
134 for(msgnum= mp->lowsel; msgnum<= mp->hghsel; msgnum++)
135 if(mp->msgstats[msgnum]&SELECTED)
136 {
137 VOID sprintf(buf,"%s%c%s", maildir,'/', m_name(msgnum));
138
139 if(string)
140 string = add("\n", string);
141 string = add(buf, string);
142 /*** printf("buf %s string %s\n",buf,string); ***/
143 }
144 return(string);
145 }
146
147
148 #include <ctype.h>
149
150 int convdir;
151 char *delimp;
152
153 #define FIRST 1 /***/
154 #define LAST 2 /***/
155
156 convert(name) /*** Slightly hacked version of ../subs/m_convert.c */
157 char *name;
158 {
159 register char *cp;
160 register int first, last;
161 int found, range, err;
162 char *bp;
163
164 found = 0;
165
166
167 if(strcmp((cp = name), "new") == 0) /***/
168 {
169 if((err = first = getnew(cp)) <= 0)
170 goto badbad;
171 goto single;
172 }
173 if(strcmp((cp = name), "all") == 0)
174 cp = "first-last";
175 if((err = first = conv(cp, FIRST)) <= 0) /***/
176 goto badbad;
177 if(*(cp = delimp) && *cp != '-' && *cp != ':') {
178 baddel: fprintf(stderr, "Illegal argument delimiter: \"%c\"\n", *delimp);
179 return(0);
180 }
181 if(*cp == '-') {
182 cp++;
183 if((err = last = conv(cp, LAST)) <= 0) { /***/
184 badbad: if(err == -1)
185 fprintf(stderr, "No %s message\n", cp);
186 else if (err == -2) /***/
187 fprintf(stderr,
188 "Message %s out of range 1-%d\n",
189 cp,MAXFOLDER);
190 else
191 badlist: fprintf(stderr, "Bad message list \"%s\".\n",
192 name);
193 return(0);
194 }
195 if(last < first) goto badlist;
196 if(*delimp) goto baddel;
197 if(first > mp->hghmsg || last < mp->lowmsg) {
198 rangerr: fprintf(stderr,"No messages in range \"%s\".\n",name);
199 return(0);
200 }
201 if(last > mp->hghmsg)
202 last = mp->hghmsg;
203 if(first < mp->lowmsg)
204 first = mp->lowmsg;
205 } else if(*cp == ':') {
206 cp++;
207 if(*cp == '-') {
208 convdir = -1;
209 cp++;
210 } else if(*cp == '+') {
211 convdir = 1;
212 cp++;
213 }
214 if((range = atoi(bp = cp)) == 0)
215 goto badlist;
216 while(isdigit(*bp)) bp++;
217 if(*bp)
218 goto baddel;
219 if((convdir > 0 && first > mp->hghmsg) ||
220 (convdir < 0 && first < mp->lowmsg))
221 goto rangerr;
222 if(first < mp->lowmsg)
223 first = mp->lowmsg;
224 if(first > mp->hghmsg)
225 first = mp->hghmsg;
226 for(last = first; last >= mp->lowmsg && last <= mp->hghmsg;
227 last += convdir)
228 if(mp->msgstats[last]&EXISTS)
229 if(--range <= 0)
230 break;
231 if(last < mp->lowmsg)
232 last = mp->lowmsg;
233 if(last > mp->hghmsg)
234 last = mp->hghmsg;
235 if(last < first) {
236 range = last; last = first; first = range;
237 }
238 } else {
239 /*** Here's the hack: cur message, single numeric message,
240 *** or new message are permitted to be non-existent
241 ***/
242 single: last = first;
243 mp->msgstats[first] |= SELECT_EMPTY;
244 }
245 while(first <= last) {
246 if(mp->msgstats[first]&(EXISTS|SELECT_EMPTY)) { /***/
247 if(!(mp->msgstats[first]&SELECTED)) {
248 mp->numsel++;
249 mp->msgstats[first] |= SELECTED;
250 if(first < mp->lowsel)
251 mp->lowsel = first;
252 if(first > mp->hghsel)
253 mp->hghsel = first;
254 }
255 found++;
256 }
257 first++;
258 }
259 if(!found)
260 goto rangerr;
261 return(1);
262 }
263
264 conv(str, callno) /*** Slightly hacked version of ../subs/m_conv.c */
265 char *str;
266 int callno; /***/
267 {
268 register char *cp, *bp;
269 register int i;
270 char buf[16];
271
272 convdir = 1;
273 cp = bp = str;
274 if(isdigit(*cp)) {
275 while(isdigit(*bp)) bp++;
276 delimp = bp;
277 /*** return (i = atoi(cp)) > MAXFOLDER ? MAXFOLDER : i; ***/
278 /* If msg # <= MAXFOLDER, return it;
279 * if > MAXFOLDER but part of a range, return MAXFOLDER;
280 * if single explicit msg #, return error.
281 */
282 return (i = atoi(cp)) <= MAXFOLDER ? i :
283 *delimp || callno == LAST ? MAXFOLDER : -2;
284 }
285 bp = buf;
286 while((*cp >= 'a' && *cp <= 'z') || *cp == '.')
287 *bp++ = *cp++;
288 *bp++ = 0;
289 delimp = cp;
290 if(strcmp(buf, "first") == 0)
291 return(mp->hghmsg? mp->lowmsg : -1); /* Folder empty? */
292 /*** return(mp->lowmsg); ***/
293 else if(strcmp(buf, "last") == 0) {
294 convdir = -1;
295 return(mp->hghmsg? mp->hghmsg : -1);
296 /*** return(mp->hghmsg); ***/
297 } else if(strcmp(buf, "cur") == 0 || strcmp(buf, ".") == 0)
298 return(mp->curmsg > 0 ? mp->curmsg : -1);
299 else if(strcmp(buf, "prev") == 0) {
300 convdir = -1;
301 for(i = (mp->curmsg<=mp->hghmsg)? mp->curmsg-1: mp->hghmsg;
302 i >= mp->lowmsg; i--) {
303 if(mp->msgstats[i]&EXISTS)
304 return(i);
305 }
306 return(-1); /* non-existent message */
307 } else if(strcmp(buf, "next") == 0) {
308 for(i = (mp->curmsg>=mp->lowmsg)? mp->curmsg+1: mp->lowmsg;
309 i <= mp->hghmsg; i++) {
310 if(mp->msgstats[i]&EXISTS)
311 return(i);
312 }
313 return(-1);
314 } else
315 return(0); /* bad message list */
316 }
317
318 getnew(str)
319 char *str;
320 {
321 register char *cp;
322
323 return(mp->hghmsg<MAXFOLDER? mp->hghmsg+ 1 :