]>
diplodocus.org Git - nmh/blob - docs/historical/mh-nov-1983/cmds/pick.c
9 #define NFOLD 20 /* Allow 20 folder specs */
11 char *anoyes
[]; /* Std no/yes gans array */
14 * pick [-src folder] [msgs] search [-scan] [-show] [file-op]
25 * file-op = -file [-preserve] [-link] +folder ...
26 * -keep [-stay] [+folder ...]
33 char grep
[256], *grepp
, *folder
, maildir
[128];
34 int showf
, scanf
, filef
, keepf
, linkf
, noteold
, prsrvf
, stayf
;
35 int grep_lowsel
= 5000,
45 } folders
[NFOLD
], *fptr
;
47 struct swit switches
[] = {
48 "cc pattern", 0, /* 0 */
49 "date pattern", 0, /* 1 */
50 "from pattern", 0, /* 2 */
51 "search pattern", 0, /* 3 */
52 "subject pattern", 0, /* 4 */
53 "to pattern", 0, /* 5 */
54 "-othercomponent pattern", 15, /* 6 */
56 "file +folder ...", 0, /* 8 */
58 "keep [+folder ...]", 0, /* 10 */
62 "preserve", 0, /* 14 */
63 "nopreserve", 0, /* 15 */
68 "src +folder", 0, /* 20 */
78 char *msgs
[128], buf
[128];
83 char *arguments
[50], **argp
, **arrp
;
85 setbuf(stdout
, _sobuf
);
94 cp
= r1bindex(argv
[0], '/');
95 if((cp
= m_find(cp
)) != NULL
) {
96 ap
= brkstring(cp
= getcpy(cp
), " ", "\n");
97 ap
= copyip(ap
, arguments
);
102 while(cp
= *argp
++) {
104 if(*++cp
== '-') { /* --component */
105 toomany
: if(grepp
!= grep
) {
106 fprintf(stderr
, "Only one search string.\n");
109 grepp
= copy("^", grepp
);
110 grepp
= copy(++cp
, grepp
);
111 grepp
= copy(":.*", grepp
);
114 switch(i
= smatch(cp
, switches
)) {
115 case -2:ambigsw(cp
, switches
); /* ambiguous */
118 case -1:fprintf(stderr
, "pick: -%s unknown\n", cp
);
121 case 0: case 1: case 2: case 4: case 5:
124 grepp
= copy("^", grepp
);
125 arrp
= brkstring(switches
[i
].sw
, " ", 0);
126 grepp
= copy(*arrp
, grepp
);
127 grepp
= copy(":.*", grepp
);
128 case 3: /* -search */
129 pattern
: grepp
= copy(*argp
++, grepp
);
131 case 6: fprintf(stderr
, "pick: can't get here\n");
134 case 7: fprintf(stderr
, "\"-all\" changed to \"all\"\n");
136 case 8: filef
= 1; continue; /* -file */
137 case 9: filef
= 0; continue; /* -nofile */
138 case 10:keepf
= 1; continue; /* -keep */
139 case 11:keepf
= 0; continue; /* -nokeep */
140 case 12:linkf
= 1; continue; /* -link */
141 case 13:linkf
= 0; continue; /* -nolink */
142 case 14:prsrvf
= 1; continue; /* -preserve */
143 case 15:prsrvf
= 0; continue; /* -nopreserve */
144 case 16:scanf
= 1; continue; /* -scan */
145 case 17:scanf
= 0; continue; /* -noscan */
146 case 18:showf
= 1; continue; /* -show */
147 case 19:showf
= 0; continue; /* -noshow */
148 case 21:stayf
= 1; continue; /* -stay */
149 case 22:stayf
= 0; continue; /* -nostay */
150 case 20:if(folder
) { /* -src */
151 fprintf(stderr
, "Only one src folder.\n");
154 if(!(folder
= *argp
++) || *folder
== '-') {
155 fprintf(stderr
, "pick: Missing argument for %s switch\n", argp
[-2]);
162 case 23:help("pick [msgs] [switches]", switches
);
165 } else if(*cp
== '+') {
167 folders
[foldp
++].f_name
= cp
+ 1;
169 fprintf(stderr
, "Only %d folders allowed.\n", NFOLD
);
176 fprintf(stderr
, "No search pattern specified.\n");
180 fprintf(stderr
, "-file and -keep don't go together.\n");
183 if(!scanf
&& !showf
&& !filef
)
184 keepf
++; /* The default is -keep */
186 prsrvf
++; /* -keep forces -preserve */
187 linkf
++; /* and -link */
190 folder
= m_getfolder(); /* use cur folder if no -src */
191 copy(m_maildir(folder
), maildir
);
192 if(chdir(maildir
) < 0) {
193 fprintf(stderr
, "Can't chdir to: ");
197 if(!(mp
= m_gmsg(folder
))) {
198 fprintf(stderr
, "Can't read folder!?\n");
201 if(mp
->hghmsg
== 0) {
202 fprintf(stderr
, "No messages in \"%s\".\n", folder
);
205 if(!foldp
) { /* if no +folder given... */
206 if(filef
) { /* -file requires one */
207 fprintf(stderr
, "-file requires at least one folder arg.\n");
210 if(keepf
) { /* use default selection-list name */
211 copy(listname
, copy("/", copy(folder
, buf
)));
212 folders
[foldp
++].f_name
= getcpy(buf
);
213 noteold
++; /* tell user if existing folder */
215 } else if(keepf
) { /* make folders sub-folders */
216 for(msgnum
= 0; msgnum
< foldp
; msgnum
++)
217 if(*(cp
= folders
[msgnum
].f_name
) != '.' &&
219 copy(cp
, copy("/", copy(folder
, buf
)));
220 folders
[msgnum
].f_name
= getcpy(buf
);
225 msgs
[msgp
++] = "first-last";
226 for(msgnum
= 0; msgnum
< msgp
; msgnum
++)
227 if(!m_convert(msgs
[msgnum
]))
229 if(mp
->numsel
== 0) {
230 fprintf(stderr
, "pick: Peanut butter 'n jelly\n");/* never get here */
234 fprintf(stderr
, "Pattern Error.\n");
237 for(msgnum
= mp
->lowsel
; msgnum
<= mp
->hghsel
; msgnum
++)
238 if(mp
->msgstats
[msgnum
]&SELECTED
)
240 if(mp
->numsel
== 0) {
241 fprintf(stderr
, "No messages match specification.\n");
244 mp
->lowsel
= grep_lowsel
;
245 mp
->hghsel
= grep_hghsel
;
247 if((((delprog
= m_find("delete-prog")) != NULL
) &&
248 ((filef
|| keepf
) && !linkf
)) ||
250 if(mp
->numsel
> MAXARGS
-2) {
251 fprintf(stderr
, "pick: more than %d messages for %s exec\n",
253 scanf
? "scan" : showf
? "show" : delprog
);
256 nvec
= (char **) malloc(MAXARGS
* sizeof nvec
[0]);
257 for(msgnum
= mp
->lowsel
; msgnum
<= mp
->hghsel
; msgnum
++)
258 if(mp
->msgstats
[msgnum
]&SELECTED
)
259 nvec
[nvecp
++] = getcpy(m_name(msgnum
));
265 if(!noteold
|| foldp
> 1)
266 m_replace(pfolder
, folder
);
268 scanfn(showf
|filef
|keepf
);
270 printf("%d hits.\n", mp
->numsel
); fflush(stdout
);
276 for(msgnum
= mp
->lowsel
; msgnum
<= mp
->hghsel
; msgnum
++)
277 if(mp
->msgstats
[msgnum
]&SELECTED
)
278 if(process(cp
= getcpy(m_name(msgnum
))))
285 if(!stayf
&& foldp
== 1) {
286 m_replace(pfolder
, cp
= folders
[0].f_name
);
287 printf("[+%s now current]\n", cp
); fflush(stdout
);
289 for(fptr
= folders
; fptr
< &folders
[foldp
]; fptr
++)
290 if(!fptr
->f_reused
) {
291 chdir(m_maildir(fptr
->f_name
));
292 m_setcur(fptr
->f_mp
->curmsg
);
302 if(execute(m_name(msg
))) { /* a match */
303 if(msg
< grep_lowsel
)
305 if(msg
> grep_hghsel
)
308 mp
->msgstats
[msg
] &= ~SELECTED
; /* clear SELECTED bit */
317 register char *cp
, *ap
;
321 for(i
= 0; i
< foldp
; i
++) {
322 copy(m_maildir(cp
= folders
[i
].f_name
), nmaildir
);
323 if(stat(nmaildir
, &stbuf
) < 0) {
325 ap
= concat("Create folder \"",
326 nmaildir
, "\"? ", 0);
327 if(!gans(ap
, anoyes
))
330 if(!makedir(nmaildir
)) {
331 fprintf(stderr
, "Can't create folder.\n");
335 printf("[Folder %s being re-used.]\n", cp
);
337 folders
[i
].f_reused
++; /* Don't change cur in old fold */
339 if(chdir(nmaildir
) < 0) {
340 fprintf(stderr
, "Can't chdir to: ");
344 if(!(folders
[i
].f_mp
= m_gmsg(folders
[i
].f_name
))) {
345 fprintf(stderr
, "Can't read folder %s\n", folders
[i
].f_name
);
348 folders
[i
].f_mp
->curmsg
= 0;
350 chdir(maildir
); /* return to src folder */
360 if(forkf
&& (pid
= fork())) {
362 fprintf(stderr
, "No forks!\n");
365 while(wait((int *)NULL
) != pid
) ;
369 execv(scanproc
, nvec
);
381 nvec
[0] = "c:mh-type";
383 sint
= (int) signal(SIGINT
, SIG_IGN
);
384 sqit
= (int) signal(SIGQUIT
, SIG_IGN
);
386 if(forkf
&& (pid
= fork())) {
388 fprintf(stderr
, "No forks!\n");
391 while(wait((int *)NULL
) != pid
) ;
392 signal(SIGINT
, sint
);
393 signal(SIGQUIT
, sqit
);
397 execv(showproc
, nvec
);
409 if(delprog
!= NULL
) {
413 execv(nvec
[0], nvec
);
414 fprintf(stderr
, "Can't exec deletion-prog--");
417 for(i
= mp
->lowsel
; i
<= mp
->hghsel
; i
++)
418 if(mp
->msgstats
[i
]&SELECTED
)
419 if(unlink(cp
= m_name(i
)) == -1) {
420 fprintf(stderr
, "Can't unlink %s:",folder
);
429 char newmsg
[256], buf
[BUFSIZ
];
432 register struct st_fold
*fp
;
433 struct stat stbuf
, stbf1
;
436 for(fp
= folders
; fp
< &folders
[foldp
]; fp
++) {
440 nmsg
= m_name(fp
->f_mp
->hghmsg
++ + 1);
441 copy(nmsg
, copy("/", copy(m_maildir(fp
->f_name
), newmsg
)));
442 if(link(msg
, newmsg
) < 0) {
444 if(linkerr
== EEXIST
||
445 (linkerr
== EXDEV
&& stat(newmsg
, &stbuf
) != -1)) {
446 if(linkerr
!= EEXIST
|| stat(msg
, &stbf1
) < 0 ||
447 stat(newmsg
, &stbuf
) < 0 ||
448 stbf1
.st_ino
!= stbuf
.st_ino
) {
449 fprintf(stderr
, "Message %s:%s already exists.\n",
455 if(linkerr
== EXDEV
) {
456 if((o
= open(msg
, 0)) == -1) {
457 fprintf(stderr
, "Can't open %s:%s.\n",
462 if((n
= creat(newmsg
, stbuf
.st_mode
&0777)) == -1) {
463 fprintf(stderr
, "Can't create %s:%s.\n",
469 if((i
=read(o
, buf
, sizeof buf
)) < 0 ||
470 write(n
, buf
, i
) == -1) {
471 fprintf(stderr
, "Copy error on %s:%s to %s:%s!\n",
472 folder
, msg
, fp
->f_name
, nmsg
);
476 while(i
== sizeof buf
);
479 fprintf(stderr
, "Error on link %s:%s to %s:",
480 folder
, msg
, fp
->f_name
);
485 if((i
= atoi(nmsg
)) < fp
->f_mp
->curmsg
|| !fp
->f_mp
->curmsg
)
486 fp
->f_mp
->curmsg
= i
;