]> diplodocus.org Git - nmh/blob - docs/historical/SRI-NOSC/file.c
Added start_test/finish_test to a bunch of tests.
[nmh] / docs / historical / SRI-NOSC / file.c
1 #include "mh.h"
2 #include "stat.h"
3 #include "errors.h"
4 #define NFOLD 20 /* Allow 20 folder specs */
5
6 /* file [-src folder] [msgs] +folder [+folder ...]
7 *
8 * moves messages from src folder (or current) to other one(s).
9 *
10 * all = first-last for a message sequence
11 * -preserve says preserve msg numbers
12 * -link says don't delete old msg
13 */
14
15 char *anoyes[]; /* Std no/yes gans array */
16
17 int fout, vecp, foldp, prsrvf;
18 char *vec[MAXARGS], maildir[128], *folder;
19 struct msgs *mp;
20
21 struct st_fold {
22 char *f_name;
23 struct msgs *f_mp;
24 } folders[NFOLD];
25
26 struct swit switches[] {
27 "all", -3, /* 0 */
28 "link", 0, /* 1 */
29 "nolink", 0, /* 2 */
30 "preserve", 0, /* 3 */
31 "nopreserve", 0, /* 4 */
32 "src +folder", 0, /* 5 */
33 "help", 4, /* 6 */
34 0, 0
35 };
36 main(argc, argv)
37 char *argv[];
38 {
39 register int i, msgnum;
40 register char *cp;
41 char *msgs[128];
42 int msgp, linkf;
43 char *ap;
44 char *arguments[50], **argp;
45
46 fout = dup(1);
47 if(argc < 2) {
48 badarg: printf("Usage: file [-src folder] [msg ...] +folder [+folder]\n");
49 goto leave;
50 }
51 #ifdef NEWS
52 m_news();
53 #endif
54 folder = msgp = linkf = 0;
55 vecp = 1;
56 ap = cp = argv[0];
57 while(*cp)
58 if(*cp++ == '/')
59 ap = cp;
60 if((cp = m_find(ap)) != -1) {
61 ap = brkstring(cp = getcpy(cp), " ", "\n");
62 ap = copyip(ap, arguments);
63 } else
64 ap = arguments;
65 copyip(argv+1, ap);
66 argp = arguments;
67 while(cp = *argp++) {
68 if(*cp == '-')
69 switch(smatch(++cp, switches)) {
70 case -2:ambigsw(cp, switches); /* ambiguous */
71 goto leave;
72 /* unknown */
73 case -1:printf("file: -%s unknown\n", cp);
74 goto leave;
75 /* -all */
76 case 0: printf("\"-all\" changed to \"all\"\n");
77 goto leave;
78 case 1: linkf = 1; continue; /* -link */
79 case 2: linkf = 0; continue; /* -nolink */
80 case 3: prsrvf = 1; continue; /* -preserve */
81 case 4: prsrvf = 0; continue; /* -nopreserve */
82 case 5: if(folder) { /* -src */
83 printf("Only one src folder.\n");
84 goto leave;
85 }
86 if(!(folder = *argp++) || *folder == '-') {
87 printf("file: Missing argument for %s switch\n", argp[-2]);
88 goto leave;
89 }
90 if(*folder == '+')
91 folder++;
92 continue;
93 /* -help */
94 case 6: help("file [msgs] [switches] +folder ...",
95 switches);
96 goto leave;
97 }
98 if(*cp == '+') {
99 if(foldp < NFOLD)
100 folders[foldp++].f_name = cp + 1;
101 else {
102 printf("Only %d folders allowed.\n", NFOLD);
103 goto leave;
104 }
105 } else
106 msgs[msgp++] = cp;
107 }
108 if(!foldp) {
109 printf("No folder specified.\n");
110 goto badarg;
111 }
112 if(!msgp)
113 msgs[msgp++] = "cur";
114 if(!folder)
115 folder = m_getfolder();
116 copy(m_maildir(folder), maildir);
117 if(chdir(maildir) < 0) {
118 printf("Can't chdir to: "); flush();
119 perror(maildir);
120 goto leave;
121 }
122 if(!(mp = m_gmsg(folder))) {
123 printf("Can't read folder %s!?\n",folder);
124 goto leave;
125 }
126 if(mp->hghmsg == 0) {
127 printf("No messages in \"%s\".\n", folder);
128 goto leave;
129 }
130 for(msgnum = 0; msgnum < msgp; msgnum++)
131 if(!m_convert((cp = msgs[msgnum]), UNDELETED, UNDELETED))
132 goto leave;
133 if(mp->numsel == 0) {
134 printf("No undeleted messages specified\n");
135 goto leave;
136 }
137 m_replace("folder", folder);
138 if(mp->hghsel != mp->curmsg && ((mp->numsel != mp->nummsg) || linkf))
139 m_setcur(mp->hghsel);
140 if(opnfolds())
141 goto leave;
142 for(msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
143 if(mp->msgstats[msgnum] & SELECTED)
144 if(process(getcpy(m_name(msgnum))))
145 goto leave;
146 if(!linkf) {
147 if((cp = m_find("delete-prog")) != -1) {
148 if(mp->numsel > MAXARGS-2) {
149 printf("file: more than %d messages for deletion-prog\n",MAXARGS-2);
150 printf("[messages not unlinked]\n");
151 goto leave;
152 }
153 for(msgnum= mp->lowsel; msgnum<= mp->hghsel; msgnum++)
154 if(mp->msgstats[msgnum]&SELECTED)
155 vec[vecp++] = getcpy(m_name(msgnum));
156 vec[vecp] = 0;
157 m_update();
158 flush();
159 vec[0] = cp;
160 execvsrh(vec);
161 printf("Can't exec deletion-prog--"); flush();
162 perror(cp);
163 } else {
164 for(msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
165 if(mp->msgstats[msgnum] & SELECTED)
166 if(unlink(cp = getcpy(m_name(msgnum)))== -1) {
167 printf("Can't unlink %s:",folder);
168 flush(); perror(cp);
169 }
170 }
171 }
172 leave:
173 m_update();
174 flush();
175 }
176
177
178 opnfolds()
179 {
180 register int i;
181 register char *cp;
182 char nmaildir[128];
183 struct inode stbuf;
184
185 for(i = 0; i < foldp; i++) {
186 copy(m_maildir(folders[i].f_name), nmaildir);
187 if(stat(nmaildir, &stbuf) < 0) {
188 cp = concat("Create folder \"", nmaildir, "\"? ", 0);
189 if(!gans(cp, anoyes))
190 goto bad;
191 free(cp);
192 if(!makedir(nmaildir)) {
193 printf("Can't create folder.\n");
194 goto bad;
195 }
196 }
197 if(chdir(nmaildir) < 0) {
198 printf("Can't chdir to: "); flush();
199 perror(nmaildir);
200 goto bad;
201 }
202 if(!(folders[i].f_mp = m_gmsg())) {
203 printf("Can't read folder %s\n", folders[i].f_name);
204 goto bad;
205 }
206 }
207 chdir(maildir); /* return to src folder */
208 return(0);
209 bad:
210 return(1);
211 }
212
213
214 process(msg)
215 {
216 char newmsg[256], buf[512];
217 register int i;
218 register char *nmsg;
219 register struct st_fold *fp;
220 struct inode stbuf, stbf1;
221 int n, o;
222
223 for(fp = folders; fp < &folders[foldp]; fp++) {
224 if(prsrvf)
225 nmsg = msg;
226 else
227 nmsg = m_name(fp->f_mp->hghmsg++ + 1);
228 copy(nmsg, copy("/", copy(m_maildir(fp->f_name), newmsg)));
229 if(link(msg, newmsg) < 0) {
230 if(errno == EEXIST ||
231 (errno == EXDEV && stat(newmsg, &stbuf) != -1)) {
232 if(errno != EEXIST || stat(msg, &stbf1) < 0 ||
233 stat(newmsg, &stbuf) < 0 ||
234 stbf1.i_number != stbuf.i_number) {
235 printf("Message %s:%s already exists.\n",
236 fp->f_name, msg);
237 return(1);
238 }
239 continue;
240 }
241 if(errno == EXDEV) {
242 if((o = open(msg, 0)) == -1) {
243 printf("Can't open %s:%s.\n",
244 folder, msg);
245 return(1);
246 }
247 fstat(o, &stbuf);
248 if((n = creat(newmsg, stbuf.i_mode&0777)) == -1) {
249 printf("Can't create %s:%s.\n",
250 fp->f_name, nmsg);
251 close(o);
252 return(1);
253 }
254 do
255 if((i=read(o, buf, sizeof buf)) < 0 ||
256 write(n, buf, i) == -1) {
257 printf("Copy error on %s:%s to %s:%s!\n",
258 folder, msg, fp->f_name, nmsg);
259 close(o); close(n);
260 return(1);
261 }
262 while(i == sizeof buf);
263 close(n); close(o);
264 } else {
265 printf("Error on link %s:%s to %s:",
266 folder, msg, fp->f_name);
267 flush();
268 perror(nmsg);
269 return(1);
270 }
271 }
272 cont: ;
273 }
274 return(0);
275 }