📄 crontab.c
字号:
int num = 0; int val = 1; (void) snprintf(tn, MAX_FNAME, CRON_TAB("tmp.XXXXXX")); fd = mkstemp(tn); if (fd < 0) { perror(tn); unlink(tn); return(-2); } if (!(tmp = fdopen(fd, "w+"))) { perror(tn); unlink(tn); return (-2); } /* copy the crontab to the the file to be rename*/ rewind(NewCrontab); while (EOF != (ch = getc(NewCrontab))) putc(ch, tmp); rewind(NewCrontab); if(!check_error()) { fprintf(stderr,"the format of your crontab is illegal\n"); unlink(tn); return -1; }#ifdef ya (void) snprintf(n, MAX_FNAME, CRON_TAB("mark")); if ((markfd=open(n, O_CREAT|O_EXCL|O_WRONLY, 0700)) == -1) { if (errno == EEXIST) { if((markfd = open(n,O_WRONLY, 0700)) == -1) { fprintf(stderr,"Can not open the mark file.\n"); exit(1); } } else { fprintf(stderr,"Can not create the mark file.\n"); exit(1); } } if((num = write(markfd,&val,sizeof(int))) < sizeof(int)) { fprintf(stderr,"write to mark file error.\n"); exit(1); }#endif (void) snprintf(n, MAX_FNAME, CRON_TAB(User)); if (rename(tn, n)) { fprintf(stderr, "%s: error renaming %s to %s\n", ProgramName, tn, n); perror("rename"); unlink(tn); return (-2); } return 0;}static int create_tmp_crontab(){ const char *template = "/crontab.XXXXXX"; int nfd; char *tmp; /* Create the temp directory. Note that since crontab is setuid(root), TMPDIR only work for root. */ strcpy(Directory,"/tmp"); if (strlen(Directory) + strlen(template) < MAX_FNAME) { strcat(Directory, template); } else { fprintf(stderr, "Tmpdir value is to long -- exiting\n"); Directory[0] = '\0'; return -1; } if (!mkdtemp(Directory)) { perror(Directory); Directory[0] = '\0'; return -1; } /* Now create the actual temporary crontab file */ if (snprintf(Filename, MAX_FNAME, "%s/crontab", Directory) >= MAX_FNAME) { fprintf(stderr, "Temporary filename too long - aborting\n"); Filename[0] = '\0'; return -1; } if ((nfd=open(Filename, O_CREAT|O_EXCL|O_WRONLY, 0700)) == -1) { perror(Filename); Filename[0] = '\0'; return -1; } return nfd;}static int clean_tmp_tab(){ DIR *dp; struct dirent *ep; char fname[MAX_FNAME]; static here = 1; if(here) { here = 0; if(Directory[0] == '\0') return -1; if((dp = opendir(Directory)) == NULL) { perror("opendir fail\n"); return -1; } while ((ep = readdir (dp))) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) { continue; } if (snprintf(fname, MAX_FNAME, "%s/%s", Directory, ep->d_name) >= MAX_FNAME) { fprintf(stderr, "filename too long to delete: %s/%s", Directory, ep->d_name); return -1; } if (unlink(fname)) { perror(ep->d_name); return -1; } } if (rmdir(Directory)) { perror(Directory); return -1; } } return 1;}static void edit_cmd(){ char n[MAX_FNAME], q[MAX_TEMPSTR], *editor; FILE *f; int ch, t, x; int waiter; int flag = 1; int fflag = 1; int ft; pid_t pid, xpid; (void) snprintf(n, MAX_FNAME, CRON_TAB(User)); if (!(f = fopen(n, "r"))) { /*no crontab before*/ /*no such file or dir*/ if (errno != ENOENT) { perror(n); exit(1); } fprintf(stderr, "no crontab for %s - using an empty one\n",User); if (!(f = fopen("/dev/null", "r"))) { perror("/dev/null"); exit(1); } } if ((t=create_tmp_crontab()) < 0) { fprintf(stderr, "Creation of temporary crontab file failed - aborting\n"); clean_tmp_tab(); exit(1); } if (!(NewCrontab = fdopen(t, "w"))) { perror("fdopen"); clean_tmp_tab(); exit(1); } /*************** copy the old crontab to tmp file ***************/ while((ch = getc(f)) != EOF) { if ('#' != ch) { putc(ch, NewCrontab); continue; } while (EOF != (ch = getc(f))) if (ch == '\n') break; if (EOF == ch) break; } fclose(f); /* Okay, edit the file */ editor = "vi"; if (fclose(NewCrontab) != 0) { perror(Filename); clean_tmp_tab(); exit(1); } /* Loop point for retrying edit after error */ /* Give up privileges while editing */ //swap_uids(); while(flag) { switch (pid = fork()) { case -1: perror("fork"); clean_tmp_tab(); exit(1); break; case 0: /* child */ if (chdir("/tmp") < 0) { perror("chdir(/tmp)"); clean_tmp_tab(); exit(1); } if (strlen(editor) + strlen(Filename) + 2 >= MAX_TEMPSTR) { fprintf(stderr, "%s: editor or filename too long\n", ProgramName); clean_tmp_tab(); exit(1); } snprintf(q, MAX_TEMPSTR, "%s %s", editor, Filename); execlp("bash","bash", "-c", q, NULL); perror(editor); clean_tmp_tab(); exit(1); default: /* parent */ break; } /* parent */ xpid = waitpid(pid, &waiter, WUNTRACED); /*************** open the tmp file for replace ***************/ if ((ft=open(Filename, O_RDONLY)) < 0) { perror("Can't open tempfile after edit"); clean_tmp_tab(); exit(1); } NewCrontab = fdopen(ft, "r"); if (!NewCrontab) { perror("fdopen(): after edit"); clean_tmp_tab(); exit(1); } fprintf(stderr, "%s: installing new crontab\n", ProgramName); switch (replace_cmd()) { case 0: flag = 0; break; case -1: while(fflag) { printf("Do you want to retry the same edit? "); fflush(stdout); q[0] = '\0'; (void) fgets(q, sizeof q, stdin); switch (islower(q[0]) ? q[0] : tolower(q[0])) { case 'y': flag = 1; fflag = 0; break; case 'n': flag = 0; fflag = 0; clean_tmp_tab(); break; default: fprintf(stderr, "Enter Y or N\n"); break; } } fflag = 1; break; case -2: flag = 0; fprintf(stderr, "%s: edits left in %s\n", ProgramName, Filename); return; default: flag = 0; fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n", ProgramName); clean_tmp_tab(); exit(1); } } clean_tmp_tab();}int main(int argc,char **argv){ int exitstatus; Pid = getpid(); parse_args(argc, argv); /* sets many globals, opens a file */ switch (Option) { case opt_list: list_cmd(); break; case opt_delete: delete_cmd(); break; case opt_edit: edit_cmd(); break; case opt_replace: if (replace_cmd() < 0) exitstatus = 1; break; case opt_unknown: usage("unknown option specified"); break; } exit(0); /*NOTREACHED*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -