chiark / gitweb /
Upstream qmail 1.01
[qmail] / instcheck.c
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include "substdio.h"
4 #include "stralloc.h"
5 #include "getln.h"
6 #include "readwrite.h"
7 #include "exit.h"
8 #include "error.h"
9 #include "strerr.h"
10 #include "byte.h"
11
12 stralloc target = {0};
13 char *to;
14
15 #define WARNING "instcheck: warning: "
16 #define FATAL "instcheck: fatal: "
17 void nomem() { strerr_die2x(111,FATAL,"out of memory"); }
18
19 void doit(line)
20 stralloc *line;
21 {
22   struct stat st;
23   char *x;
24   unsigned int xlen;
25   unsigned int i;
26   char *type;
27   char *uidstr;
28   char *gidstr;
29   char *modestr;
30   char *mid;
31   char *name;
32   unsigned long uid;
33   unsigned long gid;
34   unsigned long mode;
35   int ftype;
36
37   x = line->s; xlen = line->len;
38
39   type = x;
40   i = byte_chr(x,xlen,':'); if (i == xlen) return;
41   x[i++] = 0; x += i; xlen -= i;
42
43   uidstr = x;
44   i = byte_chr(x,xlen,':'); if (i == xlen) return;
45   x[i++] = 0; x += i; xlen -= i;
46
47   gidstr = x;
48   i = byte_chr(x,xlen,':'); if (i == xlen) return;
49   x[i++] = 0; x += i; xlen -= i;
50
51   modestr = x;
52   i = byte_chr(x,xlen,':'); if (i == xlen) return;
53   x[i++] = 0; x += i; xlen -= i;
54
55   mid = x;
56   i = byte_chr(x,xlen,':'); if (i == xlen) return;
57   x[i++] = 0; x += i; xlen -= i;
58
59   name = x;
60   i = byte_chr(x,xlen,':'); if (i == xlen) return;
61   x[i++] = 0; x += i; xlen -= i;
62
63   if (!stralloc_copys(&target,to)) nomem();
64   if (!stralloc_cats(&target,mid)) nomem();
65   if (!stralloc_cats(&target,name)) nomem();
66   if (!stralloc_0(&target)) nomem();
67
68   uid = -1; if (*uidstr) scan_ulong(uidstr,&uid);
69   gid = -1; if (*gidstr) scan_ulong(gidstr,&gid);
70   scan_8long(modestr,&mode);
71
72   switch(*type) {
73     case 'd': ftype = S_IFDIR; break;
74     case 'c': ftype = S_IFREG; break;
75     case 'z': ftype = S_IFREG; break;
76     case 'p': ftype = S_IFIFO; break;
77     default: return;
78   }
79
80   if (stat(target.s,&st) == -1) {
81     if (errno == error_noent)
82       strerr_warn3(WARNING,target.s," does not exist",0);
83     else
84       strerr_warn4(WARNING,"unable to stat ",target.s,": ",&strerr_sys);
85     return;
86   }
87
88   if ((uid != -1) && (st.st_uid != uid))
89     strerr_warn3(WARNING,target.s," has wrong owner",0);
90   if ((gid != -1) && (st.st_gid != gid))
91     strerr_warn3(WARNING,target.s," has wrong group",0);
92   if ((st.st_mode & 07777) != mode)
93     strerr_warn3(WARNING,target.s," has wrong permissions",0);
94   if ((st.st_mode & S_IFMT) != ftype)
95     strerr_warn3(WARNING,target.s," has wrong type",0);
96 }
97
98 char buf[256];
99 substdio in = SUBSTDIO_FDBUF(read,0,buf,sizeof(buf));
100 stralloc line = {0};
101
102 void main(argc,argv)
103 int argc;
104 char **argv;
105 {
106   int match;
107
108   umask(077);
109
110   to = argv[1];
111   if (!to) strerr_die2x(100,FATAL,"instcheck: usage: instcheck dir");
112
113   for (;;) {
114     if (getln(&in,&line,&match,'\n') == -1)
115       strerr_die2sys(111,FATAL,"unable to read input: ");
116     doit(&line);
117     if (!match)
118       _exit(0);
119   }
120 }