1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <dirent.h>
6 #include "ipsvd_check.h"
7 #include "sgetopt.h"
8 #include "error.h"
9 #include "open.h"
10 #include "lock.h"
11 #include "strerr.h"
12 #include "stralloc.h"
13 #include "direntry.h"
14 #include "cdb.h"
15 #include "cdb_make.h"
16 #include "str.h"
17
18 #define USAGE " cdb cdb.tmp dir"
19 #define VERSION "$Id: 940f83f1189944815f693d2f54ee1616b3f85763 $"
20 #define FATAL "ipsvd-cdb: fatal: "
21 #define WARNING "ipsvd-cdb: warning: "
22
23 const char *progname;
24 char *instdir;
25 char *cdbfn;
26 char *tmpfn;
27
28 struct cdb_make c;
29 struct cdb cdb;
30 int fdcdb;
31 int fdtmp;
32 static stralloc sa ={0};
33 static stralloc tmp ={0};
34
usage()35 void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); }
die_nomem()36 void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); }
fatal(char * m0)37 void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); }
fatal2(char * m0,char * m1)38 void fatal2(char *m0, char *m1) {
39 strerr_die5sys(111, FATAL, m0, ": ", m1, ": ");
40 }
warn(char * m0,char * m1)41 void warn(char *m0, char *m1) { strerr_warn4(WARNING, m0, ": ", m1, 0); }
42
main(int argc,char ** argv)43 int main(int argc, char **argv) {
44 int mydir;
45 DIR *dir;
46 direntry *d;
47 struct stat s;
48 int ac;
49 int i;
50
51 progname =*argv++;
52
53 if (! argv || ! *argv) usage();
54 cdbfn =*argv++;
55 if (! argv || ! *argv) usage();
56 tmpfn =*argv++;
57 if (! argv || ! *argv) usage();
58 instdir =*argv;
59
60 if ((mydir =open_read(".")) == -1)
61 fatal("unable to open current directory");
62
63 /* open cdb.tmp */
64 if ((fdtmp =open_trunc(tmpfn)) == -1) fatal2("unable to create", tmpfn);
65 if (cdb_make_start(&c, fdtmp) == -1) fatal2("unable to create", tmpfn);
66
67 if (chdir(instdir) == -1) fatal2("unable to change dir", instdir);
68 if (! (dir =opendir("."))) fatal2("unable to open dir", instdir);
69 errno =0;
70 while ((d =readdir(dir))) {
71 if (d->d_name[0] == '.') {
72 if (d->d_name[1] == 0) continue;
73 if (d->d_name[1] == '.') continue;
74 }
75 if (stat(d->d_name, &s) == -1) {
76 warn("unable to stat", d->d_name);
77 errno =0;
78 continue;
79 }
80 sa.len =0;
81 ac =ipsvd_check(0, &sa, &tmp, ".", 0, d->d_name, 0);
82 if (ac == -1) fatal2("unable to read instruction", d->d_name);
83 if (ac == IPSVD_ERR) fatal2("unable to read", "."); /* impossible? */
84
85 switch(ac) {
86 case IPSVD_EXEC:
87 sa.s[sa.len -1] ='X';
88 if (cdb_make_add(&c, d->d_name, str_len(d->d_name), sa.s, sa.len) == -1)
89 fatal2("unable to add entry", instdir);
90 continue;
91 case IPSVD_DENY:
92 if (! sa.len) {
93 if (cdb_make_add(&c, d->d_name, str_len(d->d_name), "D", 1) == -1)
94 fatal2("unable to add entry", instdir);
95 continue;
96 }
97 case IPSVD_INSTRUCT:
98 for (i =0; i < sa.len; i++) if (sa.s[i] == '\n') sa.s[i] =0;
99 sa.s[sa.len -1] ='I';
100 if (cdb_make_add(&c, d->d_name, str_len(d->d_name), sa.s, sa.len) == -1)
101 fatal2("unable to add entry", instdir);
102 continue;
103 }
104 warn("ignore", d->d_name);
105 }
106 /* catch errno? */
107 closedir(dir);
108 if (cdb_make_finish(&c) == -1) fatal2("unable to write cdb", tmpfn);
109 if (fsync(fdtmp) == -1) fatal2("unable to write cdb", tmpfn);
110 close(fdtmp);
111 if (fchdir(mydir) == -1) fatal("unable to change to previous directory");
112 close(mydir);
113 if (rename(tmpfn, cdbfn) == -1) fatal2("unable to replace", cdbfn);
114 _exit(0);
115 }
116