📄 makehistory.c
字号:
linkbuff[sizeof linkbuff - 1] = '\0'; (void)fprintf(stderr, "Bad symlink %s -> %s, %s\n", buff, linkbuff, strerror(oerrno)); if (RemoveBad) Removeit(buff); }#endif /* defined(DO_HAVE_SYMLINK) */ continue; } if (!S_ISREG(Sb.st_mode)) { (void)fprintf(stderr, "%s is not a file\n", buff); continue; } /* Open the article. */ if ((qp = QIOopen(p, QIO_BUFFER)) == NULL) { (void)fprintf(stderr, "Can't open %s, %s\n", buff, strerror(errno)); continue; } DoArticle(qp, &Sb, buff, out, RemoveBad, Update); QIOclose(qp); } (void)closedir(dp);}/*** Tell innd to add a history line.*/STATIC BOOLAddThis(line, Verbose) register char *line; BOOL Verbose;{ int i; char *arrive; char *exp; char *posted; char *paths; char *av[6]; if ((arrive = strchr(line, HIS_FIELDSEP)) == NULL || (exp = strchr(arrive + 1, HIS_SUBFIELDSEP)) == NULL || (posted = strchr(exp + 1, HIS_SUBFIELDSEP)) == NULL || (paths = strchr(exp + 1, HIS_FIELDSEP)) == NULL) { (void)fprintf(stderr, "Got bad history line \"%s\"\n", line); return FALSE; } av[0] = line; *arrive = '\0'; av[1] = arrive + 1; *exp = '\0'; av[2] = exp + 1; *posted = '\0'; av[3] = posted + 1; *paths = '\0'; av[4] = paths + 1; av[5] = NULL; if (EQ(av[2], HIS_NOEXP)) av[2] = "0"; i = ICCcommand(SC_ADDHIST, av, (char **)NULL); *arrive = HIS_FIELDSEP; *exp = HIS_SUBFIELDSEP; *posted = HIS_SUBFIELDSEP; *paths = HIS_FIELDSEP; if (i < 0) { (void)fprintf(stderr, "Can't add history line \"%s\", %s\n", line, strerror(errno)); return FALSE; } if (Verbose) (void)fprintf(stderr, "Added %s\n", line); return TRUE;}/*** Close the server link, and exit.*/STATIC NORETURNErrorExit(Updating, Stopped) BOOL Updating; BOOL Stopped;{ if (Updating) { if (!INNDrunning && Stopped && ICCgo(Reason) < 0) (void)fprintf(stderr, "Can't restart server, %s\n", strerror(errno)); if (ICCclose() < 0) (void)fprintf(stderr, "Can't close link, %s\n", strerror(errno)); } exit(1);}/*** Print a usage message and exit.*/STATIC NORETURNUsage(){ (void)fprintf(stderr, "Usage: makehistory [-f file] [-n] [-r] [-s size] [-u]\n"); exit(1); /* NOTREACHED */}intmain(ac, av) int ac; char *av[];{ register QIOSTATE *qp; register FILE *out; register char *line; register char *p; register char *q; register long count; BUFFER B; long size; int i; BOOL JustRebuild; BOOL DoRebuild; BOOL IgnoreOld; BOOL Overwrite; BOOL Update; BOOL RemoveBad; BOOL Verbose; char temp[SMBUF]; char *TempTextFile; char *tv[2]; STRING tmpdir; char *Tflag; /* Set defaults. */ TextFile = HISTORY; DoRebuild = TRUE; JustRebuild = FALSE; IgnoreOld = FALSE; Update = FALSE; RemoveBad = FALSE; Overwrite = FALSE; Verbose = FALSE; Tflag = ""; size = 0; if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = _PATH_TMP; (void)umask(NEWSUMASK); /* Parse JCL. */ while ((i = getopt(ac, av, "bf:inors:T:uv")) != EOF) switch (i) { default: Usage(); /* NOTREACHED */ case 'b': RemoveBad = TRUE; break; case 'f': TextFile = optarg; break; case 's': size = atol(optarg); /* FALLTHROUGH */ case 'i': IgnoreOld = TRUE; break; case 'n': DoRebuild = FALSE; break; case 'o': Overwrite = TRUE; IgnoreOld = TRUE; break; case 'r': JustRebuild = TRUE; break; case 'T': tmpdir = optarg; Tflag = NEW(char, 3 + strlen(optarg) + 1); (void)sprintf(Tflag, "-T %s", optarg); break; case 'u': Update = TRUE; break; case 'v': Verbose = TRUE; break; } ac -= optind; av += optind; if (ac || (Overwrite && Update) || (Verbose && !Update)) Usage(); if ((p = strrchr(TextFile, '/')) == NULL) HISTORYDIR = _PATH_NEWSLIB; else { *p = '\0'; HISTORYDIR = COPY(TextFile); *p = '/'; } /* If we're not gonna scan the database, get out. */ if (JustRebuild) { Rebuild(size, IgnoreOld, Overwrite); exit(0); } /* Get the time. Only get it once, which is good enough. */ if (GetTimeInfo(&Now) < 0) { (void)fprintf(stderr, "Can't get the time, %s\n", strerror(errno)); exit(1); } /* Open history file. */ xchdir(HISTORYDIR); if (Update || !Overwrite) { (void)sprintf(temp, "%s/histXXXXXX", tmpdir); (void)mktemp(temp); TempTextFile = COPY(temp); } else TempTextFile = NULL; if (Update) { if (ICCopen() < 0) { (void)fprintf(stderr, "Can't talk to server, %s\n", strerror(errno)); exit(1); } tv[0] = Reason; tv[1] = NULL; if (DoRebuild && ICCcommand(SC_THROTTLE, tv, (char **)NULL) < 0) { (void)fprintf(stderr, "Can't throttle innd, %s\n", strerror(errno)); exit(1); } if (dbminit(TextFile) == -1) { (void)fprintf(stderr, "Can't open dbz file, %s\n", strerror(errno)); ErrorExit(TRUE, DoRebuild); } } if ((out = fopen(TempTextFile ? TempTextFile : TextFile, "w")) == NULL) { (void)fprintf(stderr, "Can't write to history file, %s\n", strerror(errno)); exit(1); } /* Start scanning the directories. */ if ((qp = QIOopen(ACTIVE, QIO_BUFFER)) == NULL) { (void)fprintf(stderr, "Can't open %s, %s\n", ACTIVE, strerror(errno)); exit(1); } for (count = 1; (line = QIOread(qp)) != NULL; count++) { if ((p = strchr(line, ' ')) == NULL) { (void)fprintf(stderr, "Bad line %ld, \"%s\"\n", count, line); continue; } *p = '\0'; DoNewsgroup(line, out, RemoveBad, Update); } /* Test error conditions; QIOtoolong shouldn't happen. */ if (QIOtoolong(qp)) { (void)fprintf(stderr, "Line %ld is too long\n", count); ErrorExit(Update, DoRebuild); } if (QIOerror(qp)) { (void)fprintf(stderr, "Can't read %s around line %ld, %s\n", ACTIVE, count, strerror(errno)); ErrorExit(Update, DoRebuild); } if (fflush(out) == EOF || ferror(out) || fclose(out) == EOF) { (void)fprintf(stderr, "Can't close history file, %s\n", strerror(errno)); ErrorExit(Update, DoRebuild); } /* Move. */ xchdir(HISTORYDIR); if (Update) { INNDrunning = TRUE; if (dbmclose() < 0) { (void)fprintf(stderr, "Can't close DBZ file, %s\n", strerror(errno)); ErrorExit(Update, DoRebuild); } if (DoRebuild && ICCgo(Reason) < 0) { (void)fprintf(stderr, "Can't restart innd, %s\n", strerror(errno)); ErrorExit(Update, DoRebuild); } } /* Make a temporary file, sort the text file into it. */ (void)sprintf(temp, "%s/histXXXXXX", tmpdir); (void)mktemp(temp); i = 50 + strlen(TempTextFile ? TempTextFile : TextFile) + strlen(temp); p = NEW(char, i); (void)sprintf(p, "exec sort %s -t'%c' +1n -o %s %s", Tflag, HIS_FIELDSEP, temp, TempTextFile ? TempTextFile : TextFile); i = system(p) >> 8; if (i != 0) { (void)fprintf(stderr, "Can't sort history file (exit %d), %s\n", i, strerror(errno)); ErrorExit(Update, DoRebuild); } DISPOSE(p); if (TempTextFile) { if (unlink(TempTextFile) && errno != ENOENT) (void)fprintf(stderr, "Can't remove \"%s\", %s\n", TempTextFile, strerror(errno)); DISPOSE(TempTextFile); TempTextFile = NULL; } /* Open the sorted file, get ready to write the final text file. */ if ((qp = QIOopen(temp, QIO_BUFFER)) == NULL) { (void)fprintf(stderr, "Can't open work file \"%s\", %s\n", temp, strerror(errno)); ErrorExit(Update, DoRebuild); } if (!Update && (out = fopen(TextFile, "w")) == NULL) { (void)fprintf(stderr, "Can't start writing %s, %s\n", TextFile, strerror(errno)); (void)fprintf(stderr, "Work file %s untouched.\n", temp); ErrorExit(Update, DoRebuild); } /* Get space to keep the joined history lines. */ B.Size = 100; B.Used = 0; B.Data = NEW(char, B.Size); p = COPY(""); /* Read the sorted work file. */ for (count = 0; (line = QIOread(qp)) != NULL; ) { count++; if ((q = strchr(line, HIS_FIELDSEP)) == NULL) { (void)fprintf(stderr, "Work file line %ld had bad format\n", count); ErrorExit(Update, DoRebuild); } *q = '\0'; if (EQ(p, line)) { /* Same Message-ID as last time -- get filename */ if ((q = strchr(q + 1, HIS_FIELDSEP)) == NULL) { (void)fprintf(stderr, "Work file line %ld missing filename\n", count); ErrorExit(Update, DoRebuild); } i = strlen(q); if (B.Size < B.Used + i + 3) { B.Size = B.Used + i + 3; B.Data = RENEW(B.Data, char, B.Size); } *q = ' '; (void)strcpy(&B.Data[B.Used], q); B.Used += i; } else { /* Different Message-ID; end old line, start new one. */ if (*p) { if (!Update) (void)fprintf(out, "%s\n", B.Data); else if (!AddThis(B.Data, Verbose)) ErrorExit(Update, DoRebuild); } DISPOSE(p); p = COPY(line); *q = HIS_FIELDSEP; i = strlen(line); if (B.Size < i) { B.Size = i + 2; B.Data = RENEW(B.Data, char, B.Size); } (void)strcpy(B.Data, line); B.Used = i; } if (!Update && ferror(out)) { (void)fprintf(stderr, "Can't write output from line %ld, %s\n", count, strerror(errno)); ErrorExit(Update, DoRebuild); } } /* Check for errors and close. */ if (QIOtoolong(qp)) { (void)fprintf(stderr, "Line %ld is too long\n", count); ErrorExit(Update, DoRebuild); } if (QIOerror(qp)) { (void)fprintf(stderr, "Can't read work file, %s\n", strerror(errno)); ErrorExit(Update, DoRebuild); } QIOclose(qp); if (unlink(temp) && errno != ENOENT) (void)fprintf(stderr, "Can't remove \"%s\", %s\n", temp, strerror(errno)); if (*p) { /* Add tail end of last line. */ if (!Update) (void)fprintf(out, "%s\n", B.Data); else if (!AddThis(B.Data, Verbose)) ErrorExit(Update, DoRebuild); } /* Close the output file. */ if (!Update) { if (fflush(out) == EOF || fclose(out) == EOF) { (void)fprintf(stderr, "Can't close history file, %s\n", strerror(errno)); ErrorExit(Update, DoRebuild); } if (DoRebuild) Rebuild(size ? size : count, TRUE, Overwrite); } else if (ICCclose() < 0) (void)fprintf(stderr, "Can't close link, %s\n", strerror(errno)); exit(0); /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -