static diversion * read_diversions() { diversion *diversions = NULL; char linebuf[MAXDIVERTFILENAME]; static struct varbuf vb; varbufreset(&vb); varbufaddstr(&vb, admindir); varbufaddstr(&vb, "/" DIVERSIONSFILE); varbufaddc(&vb, 0); FILE *file = fopen(vb.buf, "r"); if (!file) ohshite(_("failed to open diversions file")); for (;;) { diversion *next = nfmalloc(sizeof(diversion)); if (fgets_checked(linebuf, sizeof(linebuf), file, vb.buf) < 0) break; chomp(linebuf); next->contest = strdup(linebuf); fgets_must(linebuf, sizeof(linebuf), file, vb.buf); chomp(linebuf); next->altname = strdup(linebuf); fgets_must(linebuf, sizeof(linebuf), file, vb.buf); chomp(linebuf); next->package = strdup(linebuf); next->next = diversions; diversions = next; } fclose(file); return invert_diversions_list(diversions); }
void ensure_diversions(void) { static struct varbuf vb; struct stat stab1, stab2; char linebuf[MAXDIVERTFILENAME]; FILE *file; struct diversion *ov, *oicontest, *oialtname; varbufreset(&vb); varbufaddstr(&vb, admindir); varbufaddstr(&vb, "/" DIVERSIONSFILE); varbufaddc(&vb, 0); onerr_abort++; file = fopen(vb.buf,"r"); if (!file) { if (errno != ENOENT) ohshite(_("failed to open diversions file")); if (!diversionsfile) { onerr_abort--; return; } } else if (diversionsfile) { if (fstat(fileno(diversionsfile), &stab1)) ohshite(_("failed to fstat previous diversions file")); if (fstat(fileno(file), &stab2)) ohshite(_("failed to fstat diversions file")); if (stab1.st_dev == stab2.st_dev && stab1.st_ino == stab2.st_ino) { fclose(file); onerr_abort--; return; } } if (diversionsfile) fclose(diversionsfile); diversionsfile = file; setcloexec(fileno(diversionsfile), vb.buf); for (ov = diversions; ov; ov = ov->next) { ov->useinstead->divert->camefrom->divert = NULL; ov->useinstead->divert = NULL; } diversions = NULL; if (!file) { onerr_abort--; return; } while (fgets_checked(linebuf, sizeof(linebuf), file, vb.buf) >= 0) { oicontest = nfmalloc(sizeof(struct diversion)); oialtname = nfmalloc(sizeof(struct diversion)); oialtname->camefrom = findnamenode(linebuf, 0); oialtname->useinstead = NULL; fgets_must(linebuf, sizeof(linebuf), file, vb.buf); oicontest->useinstead = findnamenode(linebuf, 0); oicontest->camefrom = NULL; fgets_must(linebuf, sizeof(linebuf), file, vb.buf); oicontest->pkg = oialtname->pkg = strcmp(linebuf, ":") ? pkg_db_find(linebuf) : NULL; if (oialtname->camefrom->divert || oicontest->useinstead->divert) ohshit(_("conflicting diversions involving `%.250s' or `%.250s'"), oialtname->camefrom->name, oicontest->useinstead->name); oialtname->camefrom->divert = oicontest; oicontest->useinstead->divert = oialtname; oicontest->next = diversions; diversions = oicontest; } onerr_abort--; }