]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/folder.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / folder.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 <sys/types.h>
11 #include <sys/stat.h>
12 #include <strings.h>
13
14 #define NFOLDERS 300
15
16 int all, hdrflag, foldp;
17 struct msgs *mp;
18 char folder[128], *folds[NFOLDERS];
19 int msgtot, foldtot, totonly, fshort;
20 int fpack;
21 struct swit switches[] = {
22 "all", 0, /* 0 */
23 "down", 0, /* 1 */
24 "fast", 0, /* 2 */
25 "nofast", 0, /* 3 */
26 "header", 0, /* 4 */
27 "noheader", 0, /* 5 */
28 "pack", 0, /* 6 */
29 "nopack", 0, /* 7 */
30 "short", -1, /* 8 */
31 "total", 0, /* 9 */
32 "nototal", 0, /*10 */
33 "up", 0, /*11 */
34 "help", 4, /*12 */
35 0, 0
36 };
37
38 extern char _sobuf[]; /* MLW standard out buffer */
39
40 /*ARGSUSED*/
41 main(argc, argv)
42 char *argv[];
43 {
44 register char *cp, *curm;
45 register int i;
46 char *argfolder;
47 int up, down, def_short = 0;
48 char *arguments[50], **argp, **ap;
49 struct stat stbf;
50 struct node *np;
51 struct { short inum;
52 char name[14];
53 int pad;
54 } ent;
55
56 invo_name = argv[0];
57 setbuf(stdout, _sobuf);
58 #ifdef NEWS
59 m_news();
60 #endif
61 up = down = 0;
62 argfolder = NULL;
63 curm = 0;
64 /* set -all if program name ends in 's' -- "folders" */
65 if(argv[0][strlen(argv[0])-1] == 's') /* Plural name?? */
66 all++;
67 cp = r1bindex(argv[0], '/');
68 if((cp = m_find(cp)) != NULL) {
69 ap = brkstring(cp = getcpy(cp), " ", "\n");
70 ap = copyip(ap, arguments);
71 } else
72 ap = arguments;
73 VOID copyip(argv+1, ap);
74 argp = arguments;
75 while(cp = *argp++) {
76 if(*cp == '-')
77 switch(smatch(++cp, switches)) {
78 case -2:ambigsw(cp, switches); /* ambiguous */
79 goto leave;
80 /* unknown */
81 case -1:fprintf(stderr, "folder: -%s unknown\n", cp);
82 goto leave;
83 case 0: all++; continue; /* -all */
84 case 1: down++; continue; /* -down */
85 case 2: /* -fast */
86 case 8: fshort = 1; continue; /* -short */
87 case 3: fshort = 0; continue; /* -nofast */
88 case 4: hdrflag = -1; continue; /* -header */
89 case 5: hdrflag = 0; continue; /* -noheader */
90 case 6: fpack = 1; continue; /* -pack */
91 case 7: fpack = 0; continue; /* -nopack */
92 case 9: all++; totonly = 1; /* -total */
93 continue;
94 case 10:if(totonly) all--; /* -nototal */
95 totonly =0; continue;
96 case 11:up++; continue; /* -up */
97 /* -help */
98 case 12:help("folder [+folder] [msg] [switches]",
99 switches);
100 goto leave;
101 }
102 if(*cp == '+') {
103 if(argfolder) {
104 fprintf(stderr, "Only one folder at a time.\n");
105 goto leave;
106 } else
107 argfolder = path(cp+1, TFOLDER);
108 } else if(curm) {
109 fprintf(stderr, "Only one current may be given.\n");
110 goto leave;
111 } else
112 curm = cp;
113 }
114 /* free() has side affects!!! */
115 if(!m_find("path")) free(path("./", TFOLDER));
116 if(all) {
117 hdrflag = 0;
118 cp = m_maildir("");
119 m_getdefs();
120 for(np = m_defs; np; np = np->n_next) {
121 if(!ssequal("cur-", np->n_name))
122 continue;
123 if(fshort) {
124 def_short++;
125 printf("%s\n", np->n_name+4);
126 } else
127 addfold(np->n_name+4);
128 }
129 if(def_short)
130 putchar('\n');
131 if(fshort) {
132 m_update();
133 VOID fflush(stdout);
134 execl(lsproc, r1bindex(lsproc, '/'), "-x", cp, 0);
135 fprintf(stderr, "Can't exec: ");
136 perror(lsproc);
137 goto leave;
138 }
139 if(chdir(cp) < 0) {
140 fprintf(stderr, "Can't chdir to: ");
141 perror(cp);
142 goto leave;
143 }
144 if((cp = m_find(pfolder)) == NULL)
145 *folder = 0;
146 else
147 VOID copy(cp, folder);
148 i = open(".", 0);
149 ent.pad = 0;
150 while(read(i, (char *)&ent.inum,
151 sizeof ent.name + sizeof ent.inum))
152 if(ent.inum && ent.name[0] != '.' &&
153 stat(ent.name, &stbf) >= 0 &&
154 (stbf.st_mode&S_IFMT) == S_IFDIR)
155 addfold(ent.name);
156 VOID close(i);
157 for(i = 0; i < foldp; i++) {
158 VOID pfold(folds[i], NULLCP); VOID fflush(stdout);
159 }
160 if(!totonly)
161 printf("\n\t\t ");
162 printf("TOTAL= %3d message%c in %d Folder%s.\n",
163 msgtot, msgtot!=1? 's':' ',
164 foldtot, foldtot!=1? "s":"");
165 } else {
166 hdrflag++;
167 if(argfolder)
168 cp = copy(argfolder, folder);
169 else
170 cp = copy(m_getfolder(), folder);
171 if(up) {
172 while(cp > folder && *cp != '/') --cp;
173 if(cp > folder)
174 *cp = 0;
175 argfolder = folder;
176 } else if(down) {
177 VOID copy(listname, copy("/", cp));
178 argfolder = folder;
179 }
180 if(pfold(folder, curm) && argfolder)
181 m_replace(pfolder, argfolder);
182 }
183
184 leave:
185 m_update();
186 done(0);
187 }
188
189
190 addfold(fold)
191 char *fold;
192 {
193 register int i,j;
194 register char *cp;
195
196 if(foldp >= NFOLDERS) {
197 fprintf(stderr, "More than %d folders!!\n", NFOLDERS);
198 done(1);
199 }
200 cp = getcpy(fold);
201 for(i = 0; i < foldp; i++)
202 if(compare(cp, folds[i]) < 0) {
203 for(j = foldp - 1; j >= i; j--)
204 folds[j+1] = folds[j];
205 foldp++;
206 folds[i] = cp;
207 return;
208 }
209 folds[foldp++] = cp;
210 return;
211 }
212
213
214 pfold(fold, curm)
215 char *fold, *curm;
216 {
217 register char *mailfile;
218 register int msgnum, hole;
219 char newmsg[8], oldmsg[8];
220
221 mailfile = m_maildir(fold);
222 if(chdir(mailfile) < 0) {
223 fprintf(stderr, "Can't chdir to: ");
224 perror(mailfile);
225 return(0);
226 }
227 if(fshort) {
228 printf("%s\n", fold);
229 return(0);
230 }
231 if(!(mp = m_gmsg(folder))) {
232 fprintf(stderr, "Can't read folder %s!?\n",folder);
233 return(0);
234 }
235 foldtot++;
236 msgtot += mp->nummsg;
237 if(fpack) {
238 for(msgnum = mp->lowmsg, hole = 1; msgnum <= mp->hghmsg; msgnum++) {
239 if(mp->msgstats[msgnum]&EXISTS) {
240 if(msgnum != hole) {
241 VOID copy(m_name(hole), newmsg);
242 VOID copy(m_name(msgnum), oldmsg);
243 if(link(oldmsg, newmsg) == -1 ||
244 unlink(oldmsg) == -1) {
245 fprintf(stderr, "Error moving %s to ", oldmsg);
246 perror(newmsg);
247 done(1);
248 }
249 if (msgnum == mp->curmsg)
250 m_setcur(mp->curmsg = hole);
251 mp->msgstats[hole] = mp->msgstats[msgnum];
252 if(msgnum == mp->lowsel)
253 mp->lowsel = hole;
254 if(msgnum == mp->hghsel)
255 mp->hghsel = hole;
256 }
257 hole++;
258 }
259 }
260 if(mp->nummsg > 0) {
261 mp->lowmsg = 1;
262 mp->hghmsg = hole - 1;
263 }
264 }
265 if(totonly)
266 goto out;
267 if(curm) {
268 if(!m_convert(curm))
269 return(0);
270 if(mp->numsel > 1) {
271 fprintf(stderr, "Can't set current msg to range: %s\n", curm);
272 return(0);
273 }
274 m_setcur(mp->curmsg = mp->hghsel);
275 }
276 if(!hdrflag++)
277 printf("\t\tFolder # of messages ( range ); cur msg (other files)\n");
278 printf("%22s", fold);
279 if(strcmp(folder, fold) == 0)
280 printf("+ ");
281 else
282 printf(" ");
283 if(mp->hghmsg == 0)
284 printf("has no messages");
285 else {
286 printf("has %3d message%s (%3d-%3d)",
287 mp->nummsg, (mp->nummsg==1)?" ":"s",
288 mp->lowmsg, mp->hghmsg);
289 if(mp->curmsg >= mp->lowmsg && mp->curmsg <= mp->hghmsg)
290 printf("; cur=%3s", m_name(mp->curmsg));
291 }
292 if(mp->selist || mp->others) {
293 printf("; (");
294 if(mp->selist) {
295 printf("%s", listname);
296 if(mp->others)
297 printf(", ");
298 }
299 if(mp->others)
300 printf("others");
301 putchar(')');
302 }
303 putchar('.');
304 putchar('\n');
305 out:
306 free( (char *)mp);
307 mp = 0;
308 return(1);
309 }
310
311
312 compare(s1, s2)
313 char *s1, *s2;
314 {
315 register char *c1, *c2;
316 register int i;
317
318 c1 = s1; c2 = s2;
319 while(*c1 || *c2)
320 if(i = *c1++ - *c2++)
321 return(i);
322 retur