#ifndef lint static char sccsid[] = "@(#)refile.c 1.1 5/26/83"; #endif #include "mh.h" #include #include #include #include #include #define NFOLD 20 /* Allow 20 folder specs */ /* file [-src folder] [msgs] +folder [+folder ...] * * moves messages from src folder (or current) to other one(s). * * all = 1-999 for a message sequence * -preserve says preserve msg numbers * -link says don't delete old msg */ char *anoyes[]; /* Std no/yes gans array */ int vecp, foldp, prsrvf; char **vec, maildir[128], *folder, *file; struct msgs *mp; struct st_fold { char *f_name; struct msgs *f_mp; } folders[NFOLD]; char *files[NFOLD + 1]; /* Vec of files to process--starts at 1! */ int filec = 1; char *bellfile = "/usr/bin/file"; extern int errno; char *rindex(); struct swit switches[] = { "all", -3, /* 0 */ "link", 0, /* 1 */ "nolink", 0, /* 2 */ "preserve", 0, /* 3 */ "nopreserve", 0, /* 4 */ "src +folder", 0, /* 5 */ "file", 0, /* 6 */ "help", 4, /* 7 */ 0, 0 }; main(argc, argv) char *argv[]; { register int i, msgnum; register char *cp; char *msgs[128]; int msgp, linkf; int ismhfile = 0; char **ap; char *arguments[50], **argp; char *pwd(), *pwds; /* * Rand has committed the sin of picking a name that already is * used (file). We fix this here since we can tell the difference * between the two (mh file has -'s and +'s always, bell file never * has them.) */ for (i=1; i= NFOLD) { fprintf(stderr, "Too many src files.\n"); goto leave; } if(!(files[filec++] = *argp) || **argp++ == '-') goto missing; continue; case 7: help("file [msgs] [switches] +folder ...", switches); goto leave; } } if(*cp == '+') { if(foldp < NFOLD) folders[foldp++].f_name = cp + 1; else { fprintf(stderr, "Only %d folders allowed.\n", NFOLD); goto leave; } } else msgs[msgp++] = cp; } if(!foldp) { fprintf(stderr, "No folder specified.\n"); fprintf(stderr, "Usage: file [-src folder] [msg ...] [switches] +folder [+folder]\n"); goto leave; } if(filec > 1) { if(msgp) { fprintf(stderr, "File: Can't mix files and messages.\n"); goto leave; } for(i = 1; i < filec; i++) if(*files[i] != '/') { if(!pwds) pwds = pwd(); files[i] = concat(pwds, "/", files[i], 0); } if(opnfolds()) goto leave; for(i = 1; i < filec; i++) { if(process(files[i])) goto leave; } if(!linkf) { if((cp = m_find("delete-prog")) != NULL) { files[0] = cp; execvp(cp, files); fprintf(stderr, "Can't exec deletion-prog--"); perror(cp); } else for(i = 1; i < filec; i++) { if(unlink(files[i]) == -1) { fprintf(stderr, "Can't unlink "); perror(files[i]); } } } goto leave; } if(!msgp) msgs[msgp++] = "cur"; if(!folder) folder = m_getfolder(); copy(m_maildir(folder), maildir); if(chdir(maildir) < 0) { fprintf(stderr, "Can't chdir to: "); perror(maildir); goto leave; } if(!(mp = m_gmsg(folder))) { fprintf(stderr, "Can't read folder %s!?\n",folder); goto leave; } if(mp->hghmsg == 0) { fprintf(stderr, "No messages in \"%s\".\n", folder); goto leave; } for(msgnum = 0; msgnum < msgp; msgnum++) if(!m_convert((cp = msgs[msgnum]))) goto leave; if(mp->numsel == 0) { fprintf(stderr, "file: ham 'n cheese\n"); /* never get here */ goto leave; } m_replace(pfolder, folder); if(mp->hghsel != mp->curmsg && ((mp->numsel != mp->nummsg) || linkf)) m_setcur(mp->hghsel); if(opnfolds()) goto leave; for(msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) if(mp->msgstats[msgnum] & SELECTED) if(process(cp = getcpy(m_name(msgnum)))) goto leave; else cndfree(cp); if(!linkf) { if((cp = m_find("delete-prog")) != NULL) { if(mp->numsel > MAXARGS-2) { fprintf(stderr, "file: more than %d messages for deletion-prog\n",MAXARGS-2); printf("[messages not unlinked]\n"); goto leave; } vecp = 1; vec = (char **) calloc(MAXARGS + 2, sizeof *vec); for(msgnum= mp->lowsel; msgnum<= mp->hghsel; msgnum++) if(mp->msgstats[msgnum]&SELECTED) vec[vecp++] = getcpy(m_name(msgnum)); vec[vecp] = 0; m_update(); fflush(stdout); vec[0] = cp; execv(vec[0], vec); fprintf(stderr, "Can't exec deletion-prog--"); perror(cp); } else { for(msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++) if(mp->msgstats[msgnum] & SELECTED) if(unlink(cp = m_name(msgnum))== -1) { fprintf(stderr, "Can't unlink %s:",folder); perror(cp); } } } leave: m_update(); done(0); } opnfolds() { register int i; register char *cp; char nmaildir[128]; for(i = 0; i < foldp; i++) { copy(m_maildir(folders[i].f_name), nmaildir); if(access(nmaildir, 5) < 0) { cp = concat("Create folder \"", nmaildir, "\"? ", 0); if(!gans(cp, anoyes)) goto bad; free(cp); if(!makedir(nmaildir)) { fprintf(stderr, "Can't create folder.\n"); goto bad; } } if(chdir(nmaildir) < 0) { fprintf(stderr, "Can't chdir to: "); perror(nmaildir); goto bad; } if(!(folders[i].f_mp = m_gmsg())) { fprintf(stderr, "Can't read folder %s\n", folders[i].f_name); goto bad; } } chdir(maildir); /* return to src folder */ return(0); bad: return(1); } process(msg) char *msg; { char newmsg[256], buf[BUFSIZ]; register int i; register char *nmsg; register struct st_fold *fp; struct stat stbuf, stbf1; int n, o, linkerr; for(fp = folders; fp < &folders[foldp]; fp++) { if(prsrvf) nmsg = msg; else nmsg = m_name(fp->f_mp->hghmsg++ + 1); copy(nmsg, copy("/", copy(m_maildir(fp->f_name), newmsg))); if(link(msg, newmsg) < 0) { linkerr = errno; if(linkerr == EEXIST || (linkerr == EXDEV && stat(newmsg, &stbuf) != -1)) { if(linkerr != EEXIST || stat(msg, &stbf1) < 0 || stat(newmsg, &stbuf) < 0 || stbf1.st_ino != stbuf.st_ino) { fprintf(stderr, "Message %s:%s already exists.\n", fp->f_name, msg); return(1); } continue; } if(linkerr == EXDEV) { if((o = open(msg, 0)) == -1) { fprintf(stderr, "Can't open %s:%s.\n", folder, msg); return(1); } fstat(o, &stbuf); if((n = creat(newmsg, stbuf.st_mode&0777)) == -1) { fprintf(stderr, "Can't create %s:%s.\n", fp->f_name, nmsg); close(o); return(1); } do if((i=read(o, buf, sizeof buf)) < 0 || write(n, buf, i) == -1) { fprintf(stderr, "Copy error on %s:%s to %s:%s!\n", folder, msg, fp->f_name, nmsg); close(o); close(n); return(1); } while(i == sizeof buf); close(n); close(o); } else { fprintf(stderr, "Error on link %s:%s to %s:", folder, msg, fp->f_name); perror(nmsg); return(1); } } cont: ; } return(0); } char * pwd() { register FILE *pp; static char curpath[128]; register int i; FILE *popen(); if((pp = popen("pwd", "r")) == NULL || fgets(curpath, sizeof curpath, pp) == NULL || pclose(pp) != 0) { fprintf(stderr, "Can't find current directory!\n"); done(1); } *rindex(curpath, '\n') = 0; /* Zap the lf */ return curpath; }