commit - 1d023088c28e4ddb3fbbb2cba531dcd929a5d276
commit + 321e4e2c02d53683e001c9033974450a9b3882c5
blob - 3be6c3c95114e1039c37328276c082a28857f1e5
blob + 9a3984ccada111db5231435f335be6e00fcedd2b
--- commands.c
+++ commands.c
break;
if (line[0] == '#')
continue;
- if (line[0] == '!')
+ if (line[0] == '!') {
+ if (savec) {
+ if (savec->handler == ctlhandler && savec->modh) {
+ saveline[0] = '\0';
+ if (savec->modh == 1)
+ (*savec->handler) (0, NULL, modhvar);
+ else
+ (*savec->handler) (0, NULL, 0);
+ }
+ savec = NULL;
+ }
continue;
+ }
/*
* Don't ignore indented comments with pound sign, otherwise
* comments won't be saved into daemon/ctl config files.
blob - f5b393c9d71f9dbe31718db7682a8101876ed4cf
blob + 775f6565df69ee34062c4c316b093cd43a0a5af7
--- ctl.c
+++ ctl.c
void restart_dhcpd(char *, char *, char *, char *, char *);
int edit_file(char *, mode_t, char *, char **);
void ctl_symlink(char *, char *, char *);
-int rule_writeline(char *, mode_t, char *);
+void rule_writeline(int, char *);
int fill_tmpfile(char **, char *, char **);
int acq_lock(char *);
void rls_lock(int);
char **xtest_args = NULL;
int rv = 0;
int nargs;
+ /* Reused across invocations of this function to accumulate config contents. */
+ static char contentpath[PATH_MAX];
+ static int contentfd = -1;
memset(&daemons1, 0, sizeof(daemons1));
daemons2 = (struct daemons2 *) genget(hname,
(char **)ctl_daemons2, sizeof(struct daemons2));
if (daemons2 == NULL || Ambiguous(daemons2)) {
- printf("%% Internal error - Invalid argument %s\n", argv[1]);
+ printf("%% Internal error - Invalid argument %s\n", hname);
return 0;
}
if (daemons2todaemons(&daemons1, daemons2))
goto done;
daemons = &daemons1;
} else if (Ambiguous(daemons)) {
- printf("%% Internal error - Ambiguous argument %s\n", argv[1]);
+ printf("%% Internal error - Ambiguous argument %s\n", hname);
return 0;
}
cli_rtable);
if (modhvar) {
+ if (argc == 0 && saveline[0] == '\0') {
+ /* install configuration file rules by renaming on top */
+ if (contentfd == -1)
+ goto done;
+ if (chmod(contentpath, daemons->mode) == 1) {
+ printf("%% chmod %o %s: %s\n", daemons->mode, tmpfile,
+ strerror(errno));
+ goto done;
+ }
+ if (rename(contentpath, tmpfile) == -1) {
+ printf("%% rename %s %s: %s\n", contentpath,
+ tmpfile, strerror(errno));
+ goto done;
+ }
+ close(contentfd);
+ contentfd = -1;
+ contentpath[0] = '\0';
+ goto done;
+ }
/* action specified or indented command specified */
if (argc == 2 && isprefix(argv[1], "rules")) {
+ if (contentfd == -1) {
+ snprintf(contentpath, sizeof(contentpath),
+ "%s.XXXXXXXXXXXXX", tmpfile);
+ contentfd = mkstemp(contentpath);
+ if (contentfd == -1) {
+ printf("%% mkstemp: %s\n", strerror(errno));
+ goto done;
+ }
+ }
/* skip 'X rules' line */
+ rv = 1;
goto done;
- }
- if (isprefix(modhvar, "rules")) {
- if (!daemons->tmpfile) {
+ } if (isprefix(modhvar, "rules")) {
+ if (contentfd == -1) {
printf("%% writeline without tmpfile\n");
goto done;
}
- /* write indented line to tmp config file */
- rule_writeline(tmpfile, daemons->mode, saveline);
+ /* write indented line to tmp content file */
+ rule_writeline(contentfd, saveline);
+ rv = 1;
goto done;
}
}
rv = 1;
done:
free(daemons1.table);
+ if (rv == 0) {
+ /* discard partially written configs */
+ if (contentpath[0]) {
+ unlink(contentpath);
+ contentpath[0] = '\0';
+ }
+ if (contentfd != -1) {
+ close(contentfd);
+ contentfd = -1;
+ }
+ }
return rv;
}
return ret;
}
-int
-rule_writeline(char *fname, mode_t mode, char *writeline)
+void
+rule_writeline(int contentfd, char *writeline)
{
- FILE *rulefile;
-
- rulefile = fopen(fname, "a");
- if (rulefile == NULL) {
- printf("%% Rule write failed: %s\n", strerror(errno));
- return(1);
- }
if (writeline[0] == ' ')
writeline++;
- fprintf(rulefile, "%s", writeline);
- fclose(rulefile);
- chmod(fname, mode);
- return(0);
+ dprintf(contentfd, "%s", writeline);
}
int