/* lpmove dest1 dest2 - move all requests from dest1 to dest2 * lpmove request ... dest - move requests to destination dest * * This command may be used only by an LP Administrator */ #include "lp.h" SCCSID("@(#)lpmove.c 3.1") int interrupt = FALSE; char errmsg[100]; char usage[] = "usage:\t%s dest1 dest2\n\t\t-or-\n\t%s request ... dest\n"; char corrupt[] = "LP system corrupted"; int moved = 0; /* number of requests moved */ char *strncpy(); main(argc, argv) int argc; char *argv[]; { int i, seqno; char d1[DESTMAX + 1], d2[DESTMAX + 1], *strcpy(); startup(argv[0]); if(argc < 3) { printf(usage, argv[0], argv[0]); exit(0); } if(! ISADMIN) fatal(ADMINMSG, 1); if(enqueue(F_NOOP, "")) fatal("scheduler is still running - can't proceed", 1); if(isdest(argv[1])) { if(argc != 3) { printf(usage, argv[0], argv[0]); exit(0); } if(! isdest(argv[2])) { sprintf(errmsg, "destination \"%s\" non-existent", argv[2]); fatal(errmsg, 1); } strncpy(d1, argv[1], DESTMAX); d1[DESTMAX] = '\0'; strncpy(d2, argv[2], DESTMAX); d2[DESTMAX] = '\0'; if(strcmp(d1, d2) == 0) fatal("destinations are identical", 1); moveall(d1, d2); printf("total of %d requests moved from %s to %s\n", moved, d1, d2); } else if(isdest(argv[argc - 1])) { strncpy(d2, argv[argc - 1], DESTMAX); d2[DESTMAX] = '\0'; for(i = 1; i < argc - 1; i++) { if(! isrequest(argv[i], d1, &seqno)) { sprintf(errmsg, "\"%s\" is not a request id", argv[i]); fatal(errmsg, 0); } else if(strcmp(d1, d2) != 0) movit(d1, seqno, d2); } printf("total of %d requests moved to %s\n", moved, d2); endoent(); } else printf(usage, argv[0], argv[0]); exit(0); } /* moveall(d1, d2) - move all requests from d1 to d2 */ moveall(d1, d2) char *d1; char *d2; { struct outq o; FILE *dir1; struct direct d; char r1[FILEMAX], r2[FILEMAX], *file1, *file2, *strncpy(); int i, saveint(); if(signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, saveint); if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, saveint); if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, saveint); if(signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, saveint); reject(d1, d2); while(getodest(&o, d1) != EOF) { strcpy(o.o_dest, d2); putoent(&o); moved++; } i = sprintf(r1, "%s/%s/", REQUEST, d1); file1 = &r1[i]; i = sprintf(r2, "%s/%s/", REQUEST, d2); file2 = &r2[i]; if((dir1 = fopen(r1, "r")) == NULL) { sprintf(errmsg, "can't open request directory %s", r1); fatal(errmsg, 0); fatal(corrupt, 1); } while(fread((char *)&d, sizeof(struct direct), 1, dir1) == 1) { if(d.d_ino != 0 && d.d_name[0] != '.') { strncpy(file1, d.d_name, DIRSIZ); *(file1 + DIRSIZ) = '\0'; strncpy(file2, d.d_name, DIRSIZ); *(file2 + DIRSIZ) = '\0'; if(link(r1, r2) == -1 || unlink(r1) == -1) { sprintf(errmsg, "can't move request %s", r1); fatal(errmsg, 0); fatal(corrupt, 1); } } } fclose(dir1); endoent(); } /* * movit(dest, seqno, newdest) - move request dest-seqno to newdest */ movit(dest, seqno, newdest) char *dest; int seqno; char *newdest; { struct outq o; int saveint(), catch(), i; char r1[FILEMAX], r2[FILEMAX], *file1, *file2; char rname[RNAMEMAX], arg[FILEMAX], type; FILE *rfile; if(getoid(&o, dest, seqno) == EOF) { sprintf(errmsg, "request \"%s-%d\" non-existent", dest, seqno); fatal(errmsg, 0); return; } if(signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, saveint); if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, saveint); if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, saveint); if(signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, saveint); strcpy(o.o_dest, newdest); putoent(&o); i = sprintf(r1, "%s/%s/", REQUEST, dest); file1 = &r1[i]; i = sprintf(r2, "%s/%s/", REQUEST, newdest); file2 = &r2[i]; sprintf(rname, "%s/%s/r-%d", REQUEST, dest, seqno); if((rfile = fopen(rname, "r")) == NULL) { sprintf(errmsg, "can't open request file %s", rname); fatal(errmsg, 0); fatal(corrupt, 1); } while(getrent(&type, arg, rfile) != EOF) { switch(type) { case R_FILE: if(*arg != '/') { strcpy(file1, arg); strcpy(file2, arg); if(link(r1, r2) == -1 || unlink(r1) == -1) { sprintf(errmsg, "can't move request %s-%d", dest, seqno); fatal(errmsg, 0); fatal(corrupt, 1); } } break; default: break; } } fclose(rfile); sprintf(file2, "r-%d", seqno); if(link(rname, r2) == -1 || unlink(rname) == -1) { sprintf(errmsg, "can't move request %s-%d", dest, seqno); fatal(errmsg, 0); fatal(corrupt, 1); } moved++; if(signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, catch); if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, catch); if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, catch); if(signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, catch); if(interrupt) { cleanup(); exit(1); } } /* * reject(d1, d2) - reject requests for destination d1 and * supply message that requests were routed to destination d2 */ reject(d1, d2) char *d1; char *d2; { sprintf(errmsg, "%s/%s -r'all requests moved to %s' %s >/dev/null 2>&1", ADMDIR, REJECT, d2, d1); system(errmsg); printf("destination %s is not accepting requests\n", d1); printf("move in progress ...\n"); fflush(stdout); } startup(name) char *name; { int catch(), cleanup(); extern char * f_name; extern int (*f_clean)(); if(signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, catch); if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, catch); if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, catch); if(signal(SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, catch); f_name = name; f_clean = cleanup; if(chdir(SPOOL) == -1) fatal("spool directory non-existent", 1); } /* catch -- catch signals */ catch() { int cleanup(); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); cleanup(); exit(1); } cleanup() { endoent(); tunlock(); } saveint() { signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); interrupt = TRUE; }