Blame


1 5cc53af9 2006-02-12 devnull #include <u.h>
2 5cc53af9 2006-02-12 devnull #include <sys/types.h>
3 5cc53af9 2006-02-12 devnull #include <pwd.h>
4 5cc53af9 2006-02-12 devnull #include <netdb.h>
5 5cdb1798 2005-10-29 devnull #include "common.h"
6 5cdb1798 2005-10-29 devnull #include <auth.h>
7 5cdb1798 2005-10-29 devnull #include <ndb.h>
8 5cdb1798 2005-10-29 devnull
9 5cdb1798 2005-10-29 devnull /*
10 5cdb1798 2005-10-29 devnull * number of predefined fd's
11 5cdb1798 2005-10-29 devnull */
12 5cdb1798 2005-10-29 devnull int nsysfile=3;
13 5cdb1798 2005-10-29 devnull
14 5cdb1798 2005-10-29 devnull static char err[Errlen];
15 5cdb1798 2005-10-29 devnull
16 5cdb1798 2005-10-29 devnull /*
17 5cdb1798 2005-10-29 devnull * return the date
18 5cdb1798 2005-10-29 devnull */
19 5cdb1798 2005-10-29 devnull extern char *
20 5cdb1798 2005-10-29 devnull thedate(void)
21 5cdb1798 2005-10-29 devnull {
22 5cdb1798 2005-10-29 devnull static char now[64];
23 5cdb1798 2005-10-29 devnull char *cp;
24 5cdb1798 2005-10-29 devnull
25 5cdb1798 2005-10-29 devnull strcpy(now, ctime(time(0)));
26 5cdb1798 2005-10-29 devnull cp = strchr(now, '\n');
27 5cdb1798 2005-10-29 devnull if(cp)
28 5cdb1798 2005-10-29 devnull *cp = 0;
29 5cdb1798 2005-10-29 devnull return now;
30 5cdb1798 2005-10-29 devnull }
31 5cdb1798 2005-10-29 devnull
32 5cdb1798 2005-10-29 devnull /*
33 5cdb1798 2005-10-29 devnull * return the user id of the current user
34 5cdb1798 2005-10-29 devnull */
35 5cdb1798 2005-10-29 devnull extern char *
36 5cdb1798 2005-10-29 devnull getlog(void)
37 5cdb1798 2005-10-29 devnull {
38 5cdb1798 2005-10-29 devnull return getuser();
39 5cdb1798 2005-10-29 devnull }
40 5cdb1798 2005-10-29 devnull
41 5cdb1798 2005-10-29 devnull /*
42 5cdb1798 2005-10-29 devnull * return the lock name (we use one lock per directory)
43 5cdb1798 2005-10-29 devnull */
44 5cdb1798 2005-10-29 devnull static String *
45 5cdb1798 2005-10-29 devnull lockname(char *path)
46 5cdb1798 2005-10-29 devnull {
47 5cdb1798 2005-10-29 devnull String *lp;
48 5cdb1798 2005-10-29 devnull char *cp;
49 5cdb1798 2005-10-29 devnull
50 5cdb1798 2005-10-29 devnull /*
51 5cdb1798 2005-10-29 devnull * get the name of the lock file
52 5cdb1798 2005-10-29 devnull */
53 5cdb1798 2005-10-29 devnull lp = s_new();
54 5cdb1798 2005-10-29 devnull cp = strrchr(path, '/');
55 5cdb1798 2005-10-29 devnull if(cp)
56 5cdb1798 2005-10-29 devnull s_nappend(lp, path, cp - path + 1);
57 5cdb1798 2005-10-29 devnull s_append(lp, "L.mbox");
58 5cdb1798 2005-10-29 devnull
59 5cdb1798 2005-10-29 devnull return lp;
60 5cdb1798 2005-10-29 devnull }
61 5cdb1798 2005-10-29 devnull
62 5cdb1798 2005-10-29 devnull int
63 5cdb1798 2005-10-29 devnull syscreatelocked(char *path, int mode, int perm)
64 5cdb1798 2005-10-29 devnull {
65 5cdb1798 2005-10-29 devnull return create(path, mode, DMEXCL|perm);
66 5cdb1798 2005-10-29 devnull }
67 5cdb1798 2005-10-29 devnull
68 5cdb1798 2005-10-29 devnull int
69 5cdb1798 2005-10-29 devnull sysopenlocked(char *path, int mode)
70 5cdb1798 2005-10-29 devnull {
71 5cdb1798 2005-10-29 devnull /* return open(path, OEXCL|mode);/**/
72 5cdb1798 2005-10-29 devnull return open(path, mode); /* until system call is fixed */
73 5cdb1798 2005-10-29 devnull }
74 5cdb1798 2005-10-29 devnull
75 5cdb1798 2005-10-29 devnull int
76 5cdb1798 2005-10-29 devnull sysunlockfile(int fd)
77 5cdb1798 2005-10-29 devnull {
78 5cdb1798 2005-10-29 devnull return close(fd);
79 5cdb1798 2005-10-29 devnull }
80 5cdb1798 2005-10-29 devnull
81 5cdb1798 2005-10-29 devnull /*
82 5cdb1798 2005-10-29 devnull * try opening a lock file. If it doesn't exist try creating it.
83 5cdb1798 2005-10-29 devnull */
84 5cdb1798 2005-10-29 devnull static int
85 5cdb1798 2005-10-29 devnull openlockfile(Mlock *l)
86 5cdb1798 2005-10-29 devnull {
87 5cdb1798 2005-10-29 devnull int fd;
88 5cdb1798 2005-10-29 devnull Dir *d;
89 5cdb1798 2005-10-29 devnull Dir nd;
90 5cdb1798 2005-10-29 devnull char *p;
91 5cdb1798 2005-10-29 devnull
92 5cdb1798 2005-10-29 devnull fd = open(s_to_c(l->name), OREAD);
93 5cdb1798 2005-10-29 devnull if(fd >= 0){
94 5cdb1798 2005-10-29 devnull l->fd = fd;
95 5cdb1798 2005-10-29 devnull return 0;
96 5cdb1798 2005-10-29 devnull }
97 5cdb1798 2005-10-29 devnull
98 5cdb1798 2005-10-29 devnull d = dirstat(s_to_c(l->name));
99 5cdb1798 2005-10-29 devnull if(d == nil){
100 5cdb1798 2005-10-29 devnull /* file doesn't exist */
101 5cdb1798 2005-10-29 devnull /* try creating it */
102 5cdb1798 2005-10-29 devnull fd = create(s_to_c(l->name), OREAD, DMEXCL|0666);
103 5cdb1798 2005-10-29 devnull if(fd >= 0){
104 5cdb1798 2005-10-29 devnull nulldir(&nd);
105 5cdb1798 2005-10-29 devnull nd.mode = DMEXCL|0666;
106 5cdb1798 2005-10-29 devnull if(dirfwstat(fd, &nd) < 0){
107 5cdb1798 2005-10-29 devnull /* if we can't chmod, don't bother */
108 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
109 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
110 5cdb1798 2005-10-29 devnull remove(s_to_c(l->name));
111 5cdb1798 2005-10-29 devnull }
112 5cdb1798 2005-10-29 devnull l->fd = fd;
113 5cdb1798 2005-10-29 devnull return 0;
114 5cdb1798 2005-10-29 devnull }
115 5cdb1798 2005-10-29 devnull
116 5cdb1798 2005-10-29 devnull /* couldn't create */
117 5cdb1798 2005-10-29 devnull /* do we have write access to the directory? */
118 5cdb1798 2005-10-29 devnull p = strrchr(s_to_c(l->name), '/');
119 5cdb1798 2005-10-29 devnull if(p != 0){
120 5cdb1798 2005-10-29 devnull *p = 0;
121 5cdb1798 2005-10-29 devnull fd = access(s_to_c(l->name), 2);
122 5cdb1798 2005-10-29 devnull *p = '/';
123 5cdb1798 2005-10-29 devnull if(fd < 0){
124 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
125 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
126 5cdb1798 2005-10-29 devnull return 0;
127 5cdb1798 2005-10-29 devnull }
128 5cdb1798 2005-10-29 devnull } else {
129 5cdb1798 2005-10-29 devnull fd = access(".", 2);
130 5cdb1798 2005-10-29 devnull if(fd < 0){
131 5cdb1798 2005-10-29 devnull /* live without the lock but log it */
132 5cdb1798 2005-10-29 devnull syslog(0, "mail", "lock error: %s: %r", s_to_c(l->name));
133 5cdb1798 2005-10-29 devnull return 0;
134 5cdb1798 2005-10-29 devnull }
135 5cdb1798 2005-10-29 devnull }
136 5cdb1798 2005-10-29 devnull } else
137 5cdb1798 2005-10-29 devnull free(d);
138 5cdb1798 2005-10-29 devnull
139 5cdb1798 2005-10-29 devnull return 1; /* try again later */
140 5cdb1798 2005-10-29 devnull }
141 5cdb1798 2005-10-29 devnull
142 5cdb1798 2005-10-29 devnull #define LSECS 5*60
143 5cdb1798 2005-10-29 devnull
144 5cdb1798 2005-10-29 devnull /*
145 5cdb1798 2005-10-29 devnull * Set a lock for a particular file. The lock is a file in the same directory
146 5cdb1798 2005-10-29 devnull * and has L. prepended to the name of the last element of the file name.
147 5cdb1798 2005-10-29 devnull */
148 5cdb1798 2005-10-29 devnull extern Mlock *
149 5cdb1798 2005-10-29 devnull syslock(char *path)
150 5cdb1798 2005-10-29 devnull {
151 5cdb1798 2005-10-29 devnull Mlock *l;
152 5cdb1798 2005-10-29 devnull int tries;
153 5cdb1798 2005-10-29 devnull
154 5cdb1798 2005-10-29 devnull l = mallocz(sizeof(Mlock), 1);
155 5cdb1798 2005-10-29 devnull if(l == 0)
156 5cdb1798 2005-10-29 devnull return nil;
157 5cdb1798 2005-10-29 devnull
158 5cdb1798 2005-10-29 devnull l->name = lockname(path);
159 5cdb1798 2005-10-29 devnull
160 5cdb1798 2005-10-29 devnull /*
161 5cdb1798 2005-10-29 devnull * wait LSECS seconds for it to unlock
162 5cdb1798 2005-10-29 devnull */
163 5cdb1798 2005-10-29 devnull for(tries = 0; tries < LSECS*2; tries++){
164 5cdb1798 2005-10-29 devnull switch(openlockfile(l)){
165 5cdb1798 2005-10-29 devnull case 0:
166 5cdb1798 2005-10-29 devnull return l;
167 5cdb1798 2005-10-29 devnull case 1:
168 5cdb1798 2005-10-29 devnull sleep(500);
169 5cdb1798 2005-10-29 devnull break;
170 5cdb1798 2005-10-29 devnull default:
171 5cdb1798 2005-10-29 devnull goto noway;
172 5cdb1798 2005-10-29 devnull }
173 5cdb1798 2005-10-29 devnull }
174 5cdb1798 2005-10-29 devnull
175 5cdb1798 2005-10-29 devnull noway:
176 5cdb1798 2005-10-29 devnull s_free(l->name);
177 5cdb1798 2005-10-29 devnull free(l);
178 5cdb1798 2005-10-29 devnull return nil;
179 5cdb1798 2005-10-29 devnull }
180 5cdb1798 2005-10-29 devnull
181 5cdb1798 2005-10-29 devnull /*
182 5cdb1798 2005-10-29 devnull * like lock except don't wait
183 5cdb1798 2005-10-29 devnull */
184 5cdb1798 2005-10-29 devnull extern Mlock *
185 5cdb1798 2005-10-29 devnull trylock(char *path)
186 5cdb1798 2005-10-29 devnull {
187 5cdb1798 2005-10-29 devnull Mlock *l;
188 5cdb1798 2005-10-29 devnull char buf[1];
189 5cdb1798 2005-10-29 devnull int fd;
190 5cdb1798 2005-10-29 devnull
191 5cdb1798 2005-10-29 devnull l = malloc(sizeof(Mlock));
192 5cdb1798 2005-10-29 devnull if(l == 0)
193 5cdb1798 2005-10-29 devnull return 0;
194 5cdb1798 2005-10-29 devnull
195 5cdb1798 2005-10-29 devnull l->name = lockname(path);
196 5cdb1798 2005-10-29 devnull if(openlockfile(l) != 0){
197 5cdb1798 2005-10-29 devnull s_free(l->name);
198 5cdb1798 2005-10-29 devnull free(l);
199 5cdb1798 2005-10-29 devnull return 0;
200 5cdb1798 2005-10-29 devnull }
201 5cdb1798 2005-10-29 devnull
202 5cdb1798 2005-10-29 devnull /* fork process to keep lock alive */
203 5cdb1798 2005-10-29 devnull switch(l->pid = rfork(RFPROC)){
204 5cdb1798 2005-10-29 devnull default:
205 5cdb1798 2005-10-29 devnull break;
206 5cdb1798 2005-10-29 devnull case 0:
207 5cdb1798 2005-10-29 devnull fd = l->fd;
208 5cdb1798 2005-10-29 devnull for(;;){
209 5cdb1798 2005-10-29 devnull sleep(1000*60);
210 5cdb1798 2005-10-29 devnull if(pread(fd, buf, 1, 0) < 0)
211 5cdb1798 2005-10-29 devnull break;
212 5cdb1798 2005-10-29 devnull }
213 5cdb1798 2005-10-29 devnull _exits(0);
214 5cdb1798 2005-10-29 devnull }
215 5cdb1798 2005-10-29 devnull return l;
216 5cdb1798 2005-10-29 devnull }
217 5cdb1798 2005-10-29 devnull
218 5cdb1798 2005-10-29 devnull extern void
219 5cdb1798 2005-10-29 devnull syslockrefresh(Mlock *l)
220 5cdb1798 2005-10-29 devnull {
221 5cdb1798 2005-10-29 devnull char buf[1];
222 5cdb1798 2005-10-29 devnull
223 5cdb1798 2005-10-29 devnull pread(l->fd, buf, 1, 0);
224 5cdb1798 2005-10-29 devnull }
225 5cdb1798 2005-10-29 devnull
226 5cdb1798 2005-10-29 devnull extern void
227 5cdb1798 2005-10-29 devnull sysunlock(Mlock *l)
228 5cdb1798 2005-10-29 devnull {
229 5cdb1798 2005-10-29 devnull if(l == 0)
230 5cdb1798 2005-10-29 devnull return;
231 5cdb1798 2005-10-29 devnull if(l->name){
232 5cdb1798 2005-10-29 devnull s_free(l->name);
233 5cdb1798 2005-10-29 devnull }
234 5cdb1798 2005-10-29 devnull if(l->fd >= 0)
235 5cdb1798 2005-10-29 devnull close(l->fd);
236 5cdb1798 2005-10-29 devnull if(l->pid > 0)
237 5cdb1798 2005-10-29 devnull postnote(PNPROC, l->pid, "time to die");
238 5cdb1798 2005-10-29 devnull free(l);
239 5cdb1798 2005-10-29 devnull }
240 5cdb1798 2005-10-29 devnull
241 5cdb1798 2005-10-29 devnull /*
242 5cdb1798 2005-10-29 devnull * Open a file. The modes are:
243 5cdb1798 2005-10-29 devnull *
244 5cdb1798 2005-10-29 devnull * l - locked
245 5cdb1798 2005-10-29 devnull * a - set append permissions
246 5cdb1798 2005-10-29 devnull * r - readable
247 5cdb1798 2005-10-29 devnull * w - writable
248 5cdb1798 2005-10-29 devnull * A - append only (doesn't exist in Bio)
249 5cdb1798 2005-10-29 devnull */
250 5cdb1798 2005-10-29 devnull extern Biobuf *
251 5cdb1798 2005-10-29 devnull sysopen(char *path, char *mode, ulong perm)
252 5cdb1798 2005-10-29 devnull {
253 5cdb1798 2005-10-29 devnull int sysperm;
254 5cdb1798 2005-10-29 devnull int sysmode;
255 5cdb1798 2005-10-29 devnull int fd;
256 5cdb1798 2005-10-29 devnull int docreate;
257 5cdb1798 2005-10-29 devnull int append;
258 5cdb1798 2005-10-29 devnull int truncate;
259 5cdb1798 2005-10-29 devnull Dir *d, nd;
260 5cdb1798 2005-10-29 devnull Biobuf *bp;
261 5cdb1798 2005-10-29 devnull
262 5cdb1798 2005-10-29 devnull /*
263 5cdb1798 2005-10-29 devnull * decode the request
264 5cdb1798 2005-10-29 devnull */
265 5cdb1798 2005-10-29 devnull sysperm = 0;
266 5cdb1798 2005-10-29 devnull sysmode = -1;
267 5cdb1798 2005-10-29 devnull docreate = 0;
268 5cdb1798 2005-10-29 devnull append = 0;
269 5cdb1798 2005-10-29 devnull truncate = 0;
270 5cdb1798 2005-10-29 devnull for(; mode && *mode; mode++)
271 5cdb1798 2005-10-29 devnull switch(*mode){
272 5cdb1798 2005-10-29 devnull case 'A':
273 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
274 5cdb1798 2005-10-29 devnull append = 1;
275 5cdb1798 2005-10-29 devnull break;
276 5cdb1798 2005-10-29 devnull case 'c':
277 5cdb1798 2005-10-29 devnull docreate = 1;
278 5cdb1798 2005-10-29 devnull break;
279 5cdb1798 2005-10-29 devnull case 'l':
280 5cdb1798 2005-10-29 devnull sysperm |= DMEXCL;
281 1b827fbc 2006-05-21 devnull sysmode |= OLOCK;
282 5cdb1798 2005-10-29 devnull break;
283 5cdb1798 2005-10-29 devnull case 'a':
284 5cdb1798 2005-10-29 devnull sysperm |= DMAPPEND;
285 5cdb1798 2005-10-29 devnull break;
286 5cdb1798 2005-10-29 devnull case 'w':
287 5cdb1798 2005-10-29 devnull if(sysmode == -1)
288 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
289 5cdb1798 2005-10-29 devnull else
290 5cdb1798 2005-10-29 devnull sysmode = ORDWR;
291 5cdb1798 2005-10-29 devnull break;
292 5cdb1798 2005-10-29 devnull case 'r':
293 5cdb1798 2005-10-29 devnull if(sysmode == -1)
294 5cdb1798 2005-10-29 devnull sysmode = OREAD;
295 5cdb1798 2005-10-29 devnull else
296 5cdb1798 2005-10-29 devnull sysmode = ORDWR;
297 5cdb1798 2005-10-29 devnull break;
298 5cdb1798 2005-10-29 devnull case 't':
299 5cdb1798 2005-10-29 devnull truncate = 1;
300 5cdb1798 2005-10-29 devnull break;
301 5cdb1798 2005-10-29 devnull default:
302 5cdb1798 2005-10-29 devnull break;
303 5cdb1798 2005-10-29 devnull }
304 5cdb1798 2005-10-29 devnull switch(sysmode){
305 5cdb1798 2005-10-29 devnull case OREAD:
306 5cdb1798 2005-10-29 devnull case OWRITE:
307 5cdb1798 2005-10-29 devnull case ORDWR:
308 5cdb1798 2005-10-29 devnull break;
309 5cdb1798 2005-10-29 devnull default:
310 5cdb1798 2005-10-29 devnull if(sysperm&DMAPPEND)
311 5cdb1798 2005-10-29 devnull sysmode = OWRITE;
312 5cdb1798 2005-10-29 devnull else
313 5cdb1798 2005-10-29 devnull sysmode = OREAD;
314 5cdb1798 2005-10-29 devnull break;
315 5cdb1798 2005-10-29 devnull }
316 5cdb1798 2005-10-29 devnull
317 5cdb1798 2005-10-29 devnull /*
318 5cdb1798 2005-10-29 devnull * create file if we need to
319 5cdb1798 2005-10-29 devnull */
320 5cdb1798 2005-10-29 devnull if(truncate)
321 5cdb1798 2005-10-29 devnull sysmode |= OTRUNC;
322 5cdb1798 2005-10-29 devnull fd = open(path, sysmode);
323 5cdb1798 2005-10-29 devnull if(fd < 0){
324 5cdb1798 2005-10-29 devnull d = dirstat(path);
325 5cdb1798 2005-10-29 devnull if(d == nil){
326 5cdb1798 2005-10-29 devnull if(docreate == 0)
327 5cdb1798 2005-10-29 devnull return 0;
328 5cdb1798 2005-10-29 devnull
329 5cdb1798 2005-10-29 devnull fd = create(path, sysmode, sysperm|perm);
330 5cdb1798 2005-10-29 devnull if(fd < 0)
331 5cdb1798 2005-10-29 devnull return 0;
332 5cdb1798 2005-10-29 devnull nulldir(&nd);
333 5cdb1798 2005-10-29 devnull nd.mode = sysperm|perm;
334 5cdb1798 2005-10-29 devnull dirfwstat(fd, &nd);
335 5cdb1798 2005-10-29 devnull } else {
336 5cdb1798 2005-10-29 devnull free(d);
337 5cdb1798 2005-10-29 devnull return 0;
338 5cdb1798 2005-10-29 devnull }
339 5cdb1798 2005-10-29 devnull }
340 5cdb1798 2005-10-29 devnull
341 5cdb1798 2005-10-29 devnull bp = (Biobuf*)malloc(sizeof(Biobuf));
342 5cdb1798 2005-10-29 devnull if(bp == 0){
343 5cdb1798 2005-10-29 devnull close(fd);
344 5cdb1798 2005-10-29 devnull return 0;
345 5cdb1798 2005-10-29 devnull }
346 5cdb1798 2005-10-29 devnull memset(bp, 0, sizeof(Biobuf));
347 5cdb1798 2005-10-29 devnull Binit(bp, fd, sysmode&~OTRUNC);
348 5cdb1798 2005-10-29 devnull
349 5cdb1798 2005-10-29 devnull if(append)
350 5cdb1798 2005-10-29 devnull Bseek(bp, 0, 2);
351 5cdb1798 2005-10-29 devnull return bp;
352 5cdb1798 2005-10-29 devnull }
353 5cdb1798 2005-10-29 devnull
354 5cdb1798 2005-10-29 devnull /*
355 5cdb1798 2005-10-29 devnull * close the file, etc.
356 5cdb1798 2005-10-29 devnull */
357 5cdb1798 2005-10-29 devnull int
358 5cdb1798 2005-10-29 devnull sysclose(Biobuf *bp)
359 5cdb1798 2005-10-29 devnull {
360 5cdb1798 2005-10-29 devnull int rv;
361 5cdb1798 2005-10-29 devnull
362 5cdb1798 2005-10-29 devnull rv = Bterm(bp);
363 5cdb1798 2005-10-29 devnull close(Bfildes(bp));
364 5cdb1798 2005-10-29 devnull free(bp);
365 5cdb1798 2005-10-29 devnull return rv;
366 5cdb1798 2005-10-29 devnull }
367 5cdb1798 2005-10-29 devnull
368 5cdb1798 2005-10-29 devnull /*
369 5cdb1798 2005-10-29 devnull * create a file
370 5cdb1798 2005-10-29 devnull */
371 5cdb1798 2005-10-29 devnull int
372 5cdb1798 2005-10-29 devnull syscreate(char *file, int mode, ulong perm)
373 5cdb1798 2005-10-29 devnull {
374 5cdb1798 2005-10-29 devnull return create(file, mode, perm);
375 5cdb1798 2005-10-29 devnull }
376 5cdb1798 2005-10-29 devnull
377 5cdb1798 2005-10-29 devnull /*
378 5cdb1798 2005-10-29 devnull * make a directory
379 5cdb1798 2005-10-29 devnull */
380 5cdb1798 2005-10-29 devnull int
381 5cdb1798 2005-10-29 devnull sysmkdir(char *file, ulong perm)
382 5cdb1798 2005-10-29 devnull {
383 5cdb1798 2005-10-29 devnull int fd;
384 5cdb1798 2005-10-29 devnull
385 5cdb1798 2005-10-29 devnull if((fd = create(file, OREAD, DMDIR|perm)) < 0)
386 5cdb1798 2005-10-29 devnull return -1;
387 5cdb1798 2005-10-29 devnull close(fd);
388 5cdb1798 2005-10-29 devnull return 0;
389 5cdb1798 2005-10-29 devnull }
390 5cdb1798 2005-10-29 devnull
391 5cdb1798 2005-10-29 devnull /*
392 5cdb1798 2005-10-29 devnull * change the group of a file
393 5cdb1798 2005-10-29 devnull */
394 5cdb1798 2005-10-29 devnull int
395 5cdb1798 2005-10-29 devnull syschgrp(char *file, char *group)
396 5cdb1798 2005-10-29 devnull {
397 5cdb1798 2005-10-29 devnull Dir nd;
398 5cdb1798 2005-10-29 devnull
399 5cdb1798 2005-10-29 devnull if(group == 0)
400 5cdb1798 2005-10-29 devnull return -1;
401 5cdb1798 2005-10-29 devnull nulldir(&nd);
402 5cdb1798 2005-10-29 devnull nd.gid = group;
403 5cdb1798 2005-10-29 devnull return dirwstat(file, &nd);
404 5cdb1798 2005-10-29 devnull }
405 5cdb1798 2005-10-29 devnull
406 5cdb1798 2005-10-29 devnull extern int
407 5cdb1798 2005-10-29 devnull sysdirreadall(int fd, Dir **d)
408 5cdb1798 2005-10-29 devnull {
409 5cdb1798 2005-10-29 devnull return dirreadall(fd, d);
410 5cdb1798 2005-10-29 devnull }
411 5cdb1798 2005-10-29 devnull
412 5cdb1798 2005-10-29 devnull /*
413 5cdb1798 2005-10-29 devnull * read in the system name
414 5cdb1798 2005-10-29 devnull */
415 5cc53af9 2006-02-12 devnull static char *unix_hostname_read(void);
416 5cdb1798 2005-10-29 devnull extern char *
417 5cdb1798 2005-10-29 devnull sysname_read(void)
418 5cdb1798 2005-10-29 devnull {
419 5cdb1798 2005-10-29 devnull static char name[128];
420 5cdb1798 2005-10-29 devnull char *cp;
421 5cdb1798 2005-10-29 devnull
422 5cdb1798 2005-10-29 devnull cp = getenv("site");
423 5cdb1798 2005-10-29 devnull if(cp == 0 || *cp == 0)
424 5cdb1798 2005-10-29 devnull cp = alt_sysname_read();
425 5cdb1798 2005-10-29 devnull if(cp == 0 || *cp == 0)
426 5cdb1798 2005-10-29 devnull cp = "kremvax";
427 5cdb1798 2005-10-29 devnull strecpy(name, name+sizeof name, cp);
428 5cdb1798 2005-10-29 devnull return name;
429 5cdb1798 2005-10-29 devnull }
430 5cdb1798 2005-10-29 devnull extern char *
431 5cdb1798 2005-10-29 devnull alt_sysname_read(void)
432 5cdb1798 2005-10-29 devnull {
433 5cc53af9 2006-02-12 devnull char *cp;
434 5cdb1798 2005-10-29 devnull static char name[128];
435 5cdb1798 2005-10-29 devnull
436 5cc53af9 2006-02-12 devnull cp = getenv("sysname");
437 5cc53af9 2006-02-12 devnull if(cp == 0 || *cp == 0)
438 5cc53af9 2006-02-12 devnull cp = unix_hostname_read();
439 5cc53af9 2006-02-12 devnull if(cp == 0 || *cp == 0)
440 5cc53af9 2006-02-12 devnull return 0;
441 5cc53af9 2006-02-12 devnull strecpy(name, name+sizeof name, cp);
442 5cdb1798 2005-10-29 devnull return name;
443 5cdb1798 2005-10-29 devnull }
444 5cc53af9 2006-02-12 devnull static char *
445 5cc53af9 2006-02-12 devnull unix_hostname_read(void)
446 5cc53af9 2006-02-12 devnull {
447 5cc53af9 2006-02-12 devnull static char hostname[256];
448 5cdb1798 2005-10-29 devnull
449 5cc53af9 2006-02-12 devnull if(gethostname(hostname, sizeof hostname) < 0)
450 5cc53af9 2006-02-12 devnull return nil;
451 5cc53af9 2006-02-12 devnull return hostname;
452 5cc53af9 2006-02-12 devnull }
453 5cc53af9 2006-02-12 devnull
454 5cdb1798 2005-10-29 devnull /*
455 5cdb1798 2005-10-29 devnull * get all names
456 5cdb1798 2005-10-29 devnull */
457 5cdb1798 2005-10-29 devnull extern char**
458 5cdb1798 2005-10-29 devnull sysnames_read(void)
459 5cdb1798 2005-10-29 devnull {
460 5cdb1798 2005-10-29 devnull static char **namev;
461 5cc53af9 2006-02-12 devnull struct hostent *h;
462 5cc53af9 2006-02-12 devnull char **p, **a;
463 5cdb1798 2005-10-29 devnull
464 5cdb1798 2005-10-29 devnull if(namev)
465 5cdb1798 2005-10-29 devnull return namev;
466 5cdb1798 2005-10-29 devnull
467 5cc53af9 2006-02-12 devnull h = gethostbyname(alt_sysname_read());
468 5cc53af9 2006-02-12 devnull for(p=h->h_aliases; *p; p++)
469 5cc53af9 2006-02-12 devnull ;
470 5cc53af9 2006-02-12 devnull
471 5cc53af9 2006-02-12 devnull namev = malloc((2+p-h->h_aliases)*sizeof namev[0]);
472 5cc53af9 2006-02-12 devnull if(namev == 0)
473 5cc53af9 2006-02-12 devnull return 0;
474 5cdb1798 2005-10-29 devnull
475 5cc53af9 2006-02-12 devnull a = namev;
476 5cc53af9 2006-02-12 devnull *a++ = strdup(h->h_name);
477 5cc53af9 2006-02-12 devnull for(p=h->h_aliases; *p; p++)
478 5cc53af9 2006-02-12 devnull *a++ = strdup(*p);
479 5cc53af9 2006-02-12 devnull *a = 0;
480 5cdb1798 2005-10-29 devnull
481 5cdb1798 2005-10-29 devnull return namev;
482 5cdb1798 2005-10-29 devnull }
483 5cdb1798 2005-10-29 devnull
484 5cdb1798 2005-10-29 devnull /*
485 5cc53af9 2006-02-12 devnull * read in the domain name.
486 5cc53af9 2006-02-12 devnull * chop off beginning pieces until we find one with an mx record.
487 5cdb1798 2005-10-29 devnull */
488 5cdb1798 2005-10-29 devnull extern char *
489 5cdb1798 2005-10-29 devnull domainname_read(void)
490 5cdb1798 2005-10-29 devnull {
491 5cc53af9 2006-02-12 devnull char **namev, *p;
492 5cc53af9 2006-02-12 devnull Ndbtuple *t;
493 5cdb1798 2005-10-29 devnull
494 5cc53af9 2006-02-12 devnull for(namev = sysnames_read(); *namev; namev++){
495 5cc53af9 2006-02-12 devnull if(strchr(*namev, '.')){
496 5cc53af9 2006-02-12 devnull for(p=*namev-1; p && *++p; p=strchr(p, '.')){
497 5cc53af9 2006-02-12 devnull if((t = dnsquery(nil, p, "mx")) != nil){
498 5cc53af9 2006-02-12 devnull ndbfree(t);
499 5cc53af9 2006-02-12 devnull return p;
500 5cc53af9 2006-02-12 devnull }
501 5cc53af9 2006-02-12 devnull }
502 5cc53af9 2006-02-12 devnull }
503 5cc53af9 2006-02-12 devnull }
504 5cdb1798 2005-10-29 devnull return 0;
505 5cdb1798 2005-10-29 devnull }
506 5cdb1798 2005-10-29 devnull
507 5cdb1798 2005-10-29 devnull /*
508 5cdb1798 2005-10-29 devnull * return true if the last error message meant file
509 5cdb1798 2005-10-29 devnull * did not exist.
510 5cdb1798 2005-10-29 devnull */
511 5cdb1798 2005-10-29 devnull extern int
512 5cdb1798 2005-10-29 devnull e_nonexistent(void)
513 5cdb1798 2005-10-29 devnull {
514 5cdb1798 2005-10-29 devnull rerrstr(err, sizeof(err));
515 5cdb1798 2005-10-29 devnull return strcmp(err, "file does not exist") == 0;
516 5cdb1798 2005-10-29 devnull }
517 5cdb1798 2005-10-29 devnull
518 5cdb1798 2005-10-29 devnull /*
519 5cdb1798 2005-10-29 devnull * return true if the last error message meant file
520 5cdb1798 2005-10-29 devnull * was locked.
521 5cdb1798 2005-10-29 devnull */
522 5cdb1798 2005-10-29 devnull extern int
523 5cdb1798 2005-10-29 devnull e_locked(void)
524 5cdb1798 2005-10-29 devnull {
525 5cdb1798 2005-10-29 devnull rerrstr(err, sizeof(err));
526 5cdb1798 2005-10-29 devnull return strcmp(err, "open/create -- file is locked") == 0;
527 5cdb1798 2005-10-29 devnull }
528 5cdb1798 2005-10-29 devnull
529 5cdb1798 2005-10-29 devnull /*
530 5cdb1798 2005-10-29 devnull * return the length of a file
531 5cdb1798 2005-10-29 devnull */
532 5cdb1798 2005-10-29 devnull extern long
533 5cdb1798 2005-10-29 devnull sysfilelen(Biobuf *fp)
534 5cdb1798 2005-10-29 devnull {
535 5cdb1798 2005-10-29 devnull Dir *d;
536 5cdb1798 2005-10-29 devnull long rv;
537 5cdb1798 2005-10-29 devnull
538 5cdb1798 2005-10-29 devnull d = dirfstat(Bfildes(fp));
539 5cdb1798 2005-10-29 devnull if(d == nil)
540 5cdb1798 2005-10-29 devnull return -1;
541 5cdb1798 2005-10-29 devnull rv = d->length;
542 5cdb1798 2005-10-29 devnull free(d);
543 5cdb1798 2005-10-29 devnull return rv;
544 5cdb1798 2005-10-29 devnull }
545 5cdb1798 2005-10-29 devnull
546 5cdb1798 2005-10-29 devnull /*
547 5cdb1798 2005-10-29 devnull * remove a file
548 5cdb1798 2005-10-29 devnull */
549 5cdb1798 2005-10-29 devnull extern int
550 5cdb1798 2005-10-29 devnull sysremove(char *path)
551 5cdb1798 2005-10-29 devnull {
552 5cdb1798 2005-10-29 devnull return remove(path);
553 5cdb1798 2005-10-29 devnull }
554 5cdb1798 2005-10-29 devnull
555 5cdb1798 2005-10-29 devnull /*
556 5cdb1798 2005-10-29 devnull * rename a file, fails unless both are in the same directory
557 5cdb1798 2005-10-29 devnull */
558 5cdb1798 2005-10-29 devnull extern int
559 5cdb1798 2005-10-29 devnull sysrename(char *old, char *new)
560 5cdb1798 2005-10-29 devnull {
561 5cdb1798 2005-10-29 devnull Dir d;
562 5cdb1798 2005-10-29 devnull char *obase;
563 5cdb1798 2005-10-29 devnull char *nbase;
564 5cdb1798 2005-10-29 devnull
565 5cdb1798 2005-10-29 devnull obase = strrchr(old, '/');
566 5cdb1798 2005-10-29 devnull nbase = strrchr(new, '/');
567 5cdb1798 2005-10-29 devnull if(obase){
568 5cdb1798 2005-10-29 devnull if(nbase == 0)
569 5cdb1798 2005-10-29 devnull return -1;
570 5cdb1798 2005-10-29 devnull if(strncmp(old, new, obase-old) != 0)
571 5cdb1798 2005-10-29 devnull return -1;
572 5cdb1798 2005-10-29 devnull nbase++;
573 5cdb1798 2005-10-29 devnull } else {
574 5cdb1798 2005-10-29 devnull if(nbase)
575 5cdb1798 2005-10-29 devnull return -1;
576 5cdb1798 2005-10-29 devnull nbase = new;
577 5cdb1798 2005-10-29 devnull }
578 5cdb1798 2005-10-29 devnull nulldir(&d);
579 5cdb1798 2005-10-29 devnull d.name = nbase;
580 5cdb1798 2005-10-29 devnull return dirwstat(old, &d);
581 5cdb1798 2005-10-29 devnull }
582 5cdb1798 2005-10-29 devnull
583 5cdb1798 2005-10-29 devnull /*
584 5cdb1798 2005-10-29 devnull * see if a file exists
585 5cdb1798 2005-10-29 devnull */
586 5cdb1798 2005-10-29 devnull extern int
587 5cdb1798 2005-10-29 devnull sysexist(char *file)
588 5cdb1798 2005-10-29 devnull {
589 5cdb1798 2005-10-29 devnull Dir *d;
590 5cdb1798 2005-10-29 devnull
591 5cdb1798 2005-10-29 devnull d = dirstat(file);
592 5cdb1798 2005-10-29 devnull if(d == nil)
593 5cdb1798 2005-10-29 devnull return 0;
594 5cdb1798 2005-10-29 devnull free(d);
595 5cdb1798 2005-10-29 devnull return 1;
596 5cdb1798 2005-10-29 devnull }
597 5cdb1798 2005-10-29 devnull
598 5cdb1798 2005-10-29 devnull /*
599 5cdb1798 2005-10-29 devnull * return nonzero if file is a directory
600 5cdb1798 2005-10-29 devnull */
601 5cdb1798 2005-10-29 devnull extern int
602 5cdb1798 2005-10-29 devnull sysisdir(char *file)
603 5cdb1798 2005-10-29 devnull {
604 5cdb1798 2005-10-29 devnull Dir *d;
605 5cdb1798 2005-10-29 devnull int rv;
606 5cdb1798 2005-10-29 devnull
607 5cdb1798 2005-10-29 devnull d = dirstat(file);
608 5cdb1798 2005-10-29 devnull if(d == nil)
609 5cdb1798 2005-10-29 devnull return 0;
610 5cdb1798 2005-10-29 devnull rv = d->mode & DMDIR;
611 5cdb1798 2005-10-29 devnull free(d);
612 5cdb1798 2005-10-29 devnull return rv;
613 5cdb1798 2005-10-29 devnull }
614 5cdb1798 2005-10-29 devnull
615 5cdb1798 2005-10-29 devnull /*
616 5cdb1798 2005-10-29 devnull * kill a process
617 5cdb1798 2005-10-29 devnull */
618 5cdb1798 2005-10-29 devnull extern int
619 5cdb1798 2005-10-29 devnull syskill(int pid)
620 5cdb1798 2005-10-29 devnull {
621 5cc53af9 2006-02-12 devnull return postnote(PNPROC, pid, "kill");
622 5cdb1798 2005-10-29 devnull }
623 5cdb1798 2005-10-29 devnull
624 5cdb1798 2005-10-29 devnull /*
625 5cdb1798 2005-10-29 devnull * kill a process group
626 5cdb1798 2005-10-29 devnull */
627 5cdb1798 2005-10-29 devnull extern int
628 5cdb1798 2005-10-29 devnull syskillpg(int pid)
629 5cdb1798 2005-10-29 devnull {
630 5cc53af9 2006-02-12 devnull return postnote(PNGROUP, pid, "kill");
631 5cdb1798 2005-10-29 devnull }
632 5cdb1798 2005-10-29 devnull
633 5cdb1798 2005-10-29 devnull extern int
634 5cdb1798 2005-10-29 devnull sysdetach(void)
635 5cdb1798 2005-10-29 devnull {
636 5cdb1798 2005-10-29 devnull if(rfork(RFENVG|RFNAMEG|RFNOTEG) < 0) {
637 5cdb1798 2005-10-29 devnull werrstr("rfork failed");
638 5cdb1798 2005-10-29 devnull return -1;
639 5cdb1798 2005-10-29 devnull }
640 5cdb1798 2005-10-29 devnull return 0;
641 5cdb1798 2005-10-29 devnull }
642 5cdb1798 2005-10-29 devnull
643 5cdb1798 2005-10-29 devnull /*
644 5cdb1798 2005-10-29 devnull * catch a write on a closed pipe
645 5cdb1798 2005-10-29 devnull */
646 5cdb1798 2005-10-29 devnull static int *closedflag;
647 5cdb1798 2005-10-29 devnull static int
648 5cdb1798 2005-10-29 devnull catchpipe(void *a, char *msg)
649 5cdb1798 2005-10-29 devnull {
650 5cdb1798 2005-10-29 devnull static char *foo = "sys: write on closed pipe";
651 5cdb1798 2005-10-29 devnull
652 5cdb1798 2005-10-29 devnull USED(a);
653 5cdb1798 2005-10-29 devnull if(strncmp(msg, foo, strlen(foo)) == 0){
654 5cdb1798 2005-10-29 devnull if(closedflag)
655 5cdb1798 2005-10-29 devnull *closedflag = 1;
656 5cdb1798 2005-10-29 devnull return 1;
657 5cdb1798 2005-10-29 devnull }
658 5cdb1798 2005-10-29 devnull return 0;
659 5cdb1798 2005-10-29 devnull }
660 5cdb1798 2005-10-29 devnull void
661 5cdb1798 2005-10-29 devnull pipesig(int *flagp)
662 5cdb1798 2005-10-29 devnull {
663 5cdb1798 2005-10-29 devnull closedflag = flagp;
664 5cdb1798 2005-10-29 devnull atnotify(catchpipe, 1);
665 5cdb1798 2005-10-29 devnull }
666 5cdb1798 2005-10-29 devnull void
667 5cdb1798 2005-10-29 devnull pipesigoff(void)
668 5cdb1798 2005-10-29 devnull {
669 5cdb1798 2005-10-29 devnull atnotify(catchpipe, 0);
670 5cdb1798 2005-10-29 devnull }
671 5cdb1798 2005-10-29 devnull
672 5cdb1798 2005-10-29 devnull extern int
673 5cdb1798 2005-10-29 devnull holdon(void)
674 5cdb1798 2005-10-29 devnull {
675 605c0ea1 2006-02-08 devnull /* XXX talk to 9term? */
676 605c0ea1 2006-02-08 devnull return -1;
677 5cdb1798 2005-10-29 devnull }
678 5cdb1798 2005-10-29 devnull
679 5cdb1798 2005-10-29 devnull extern int
680 5cdb1798 2005-10-29 devnull sysopentty(void)
681 5cdb1798 2005-10-29 devnull {
682 605c0ea1 2006-02-08 devnull return open("/dev/tty", ORDWR);
683 5cdb1798 2005-10-29 devnull }
684 5cdb1798 2005-10-29 devnull
685 5cdb1798 2005-10-29 devnull extern void
686 5cdb1798 2005-10-29 devnull holdoff(int fd)
687 5cdb1798 2005-10-29 devnull {
688 5cdb1798 2005-10-29 devnull write(fd, "holdoff", 7);
689 5cdb1798 2005-10-29 devnull close(fd);
690 5cdb1798 2005-10-29 devnull }
691 5cdb1798 2005-10-29 devnull
692 5cdb1798 2005-10-29 devnull extern int
693 5cdb1798 2005-10-29 devnull sysfiles(void)
694 5cdb1798 2005-10-29 devnull {
695 5cdb1798 2005-10-29 devnull return 128;
696 5cdb1798 2005-10-29 devnull }
697 5cdb1798 2005-10-29 devnull
698 5cdb1798 2005-10-29 devnull /*
699 5cdb1798 2005-10-29 devnull * expand a path relative to the user's mailbox directory
700 5cdb1798 2005-10-29 devnull *
701 5cdb1798 2005-10-29 devnull * if the path starts with / or ./, don't change it
702 5cdb1798 2005-10-29 devnull *
703 5cdb1798 2005-10-29 devnull */
704 5cdb1798 2005-10-29 devnull extern String *
705 5cdb1798 2005-10-29 devnull mboxpath(char *path, char *user, String *to, int dot)
706 5cdb1798 2005-10-29 devnull {
707 5cc53af9 2006-02-12 devnull char *dir;
708 5cc53af9 2006-02-12 devnull String *s;
709 5cc53af9 2006-02-12 devnull
710 5cdb1798 2005-10-29 devnull if (dot || *path=='/' || strncmp(path, "./", 2) == 0
711 5cdb1798 2005-10-29 devnull || strncmp(path, "../", 3) == 0) {
712 5cdb1798 2005-10-29 devnull to = s_append(to, path);
713 5cdb1798 2005-10-29 devnull } else {
714 5cc53af9 2006-02-12 devnull if ((dir = homedir(user)) != nil) {
715 5cc53af9 2006-02-12 devnull s = s_copy(dir);
716 5cc53af9 2006-02-12 devnull s_append(s, "/mail/");
717 5cc53af9 2006-02-12 devnull if(access(s_to_c(s), AEXIST) >= 0){
718 5cc53af9 2006-02-12 devnull to = s_append(to, s_to_c(s));
719 5cc53af9 2006-02-12 devnull s_free(s);
720 5cc53af9 2006-02-12 devnull to = s_append(to, path);
721 5cc53af9 2006-02-12 devnull return to;
722 5cc53af9 2006-02-12 devnull }
723 5cc53af9 2006-02-12 devnull s_free(s);
724 5cc53af9 2006-02-12 devnull }
725 605c0ea1 2006-02-08 devnull to = s_append(to, MAILROOT);
726 5cdb1798 2005-10-29 devnull to = s_append(to, "/box/");
727 5cdb1798 2005-10-29 devnull to = s_append(to, user);
728 5cdb1798 2005-10-29 devnull to = s_append(to, "/");
729 5cdb1798 2005-10-29 devnull to = s_append(to, path);
730 5cdb1798 2005-10-29 devnull }
731 5cdb1798 2005-10-29 devnull return to;
732 5cdb1798 2005-10-29 devnull }
733 5cdb1798 2005-10-29 devnull
734 5cdb1798 2005-10-29 devnull extern String *
735 5cdb1798 2005-10-29 devnull mboxname(char *user, String *to)
736 5cdb1798 2005-10-29 devnull {
737 5cdb1798 2005-10-29 devnull return mboxpath("mbox", user, to, 0);
738 5cdb1798 2005-10-29 devnull }
739 5cdb1798 2005-10-29 devnull
740 5cdb1798 2005-10-29 devnull extern String *
741 5cdb1798 2005-10-29 devnull deadletter(String *to) /* pass in sender??? */
742 5cdb1798 2005-10-29 devnull {
743 5cdb1798 2005-10-29 devnull char *cp;
744 5cdb1798 2005-10-29 devnull
745 5cdb1798 2005-10-29 devnull cp = getlog();
746 5cdb1798 2005-10-29 devnull if(cp == 0)
747 5cdb1798 2005-10-29 devnull return 0;
748 5cdb1798 2005-10-29 devnull return mboxpath("dead.letter", cp, to, 0);
749 5cdb1798 2005-10-29 devnull }
750 5cdb1798 2005-10-29 devnull
751 5cdb1798 2005-10-29 devnull String *
752 5cdb1798 2005-10-29 devnull readlock(String *file)
753 5cdb1798 2005-10-29 devnull {
754 5cdb1798 2005-10-29 devnull char *cp;
755 5cdb1798 2005-10-29 devnull
756 5cdb1798 2005-10-29 devnull cp = getlog();
757 5cdb1798 2005-10-29 devnull if(cp == 0)
758 5cdb1798 2005-10-29 devnull return 0;
759 5cdb1798 2005-10-29 devnull return mboxpath("reading", cp, file, 0);
760 5cdb1798 2005-10-29 devnull }
761 5cdb1798 2005-10-29 devnull
762 5cdb1798 2005-10-29 devnull String *
763 5cdb1798 2005-10-29 devnull username(String *from)
764 5cdb1798 2005-10-29 devnull {
765 5cc53af9 2006-02-12 devnull String* s;
766 5cc53af9 2006-02-12 devnull struct passwd* pw;
767 5cdb1798 2005-10-29 devnull
768 5cc53af9 2006-02-12 devnull setpwent();
769 5cc53af9 2006-02-12 devnull while((pw = getpwent()) != nil){
770 5cc53af9 2006-02-12 devnull if(strcmp(s_to_c(from), pw->pw_name) == 0){
771 5cc53af9 2006-02-12 devnull s = s_new();
772 5cc53af9 2006-02-12 devnull s_append(s, "\"");
773 5cc53af9 2006-02-12 devnull s_append(s, pw->pw_gecos);
774 5cc53af9 2006-02-12 devnull s_append(s, "\"");
775 5cc53af9 2006-02-12 devnull return s;
776 5cc53af9 2006-02-12 devnull }
777 5cc53af9 2006-02-12 devnull }
778 5cc53af9 2006-02-12 devnull return nil;
779 5cc53af9 2006-02-12 devnull }
780 5cdb1798 2005-10-29 devnull
781 5cc53af9 2006-02-12 devnull char *
782 5cc53af9 2006-02-12 devnull homedir(char *user)
783 5cc53af9 2006-02-12 devnull {
784 5cc53af9 2006-02-12 devnull static char buf[1024];
785 5cc53af9 2006-02-12 devnull struct passwd* pw;
786 5cc53af9 2006-02-12 devnull
787 5cc53af9 2006-02-12 devnull setpwent();
788 5cc53af9 2006-02-12 devnull while((pw = getpwent()) != nil)
789 5cc53af9 2006-02-12 devnull if(strcmp(user, pw->pw_name) == 0){
790 5cc53af9 2006-02-12 devnull strecpy(buf, buf+sizeof buf, pw->pw_dir);
791 5cc53af9 2006-02-12 devnull return buf;
792 5cc53af9 2006-02-12 devnull }
793 5cc53af9 2006-02-12 devnull return nil;
794 5cdb1798 2005-10-29 devnull }
795 5cdb1798 2005-10-29 devnull
796 5cdb1798 2005-10-29 devnull char *
797 5cdb1798 2005-10-29 devnull remoteaddr(int fd, char *dir)
798 5cdb1798 2005-10-29 devnull {
799 5cc53af9 2006-02-12 devnull char *raddr;
800 5cc53af9 2006-02-12 devnull NetConnInfo *nci;
801 5cc53af9 2006-02-12 devnull
802 5cc53af9 2006-02-12 devnull if((nci = getnetconninfo(dir, fd)) == nil)
803 5cc53af9 2006-02-12 devnull return nil;
804 5cc53af9 2006-02-12 devnull raddr = strdup(nci->raddr);
805 5cc53af9 2006-02-12 devnull freenetconninfo(nci);
806 5cc53af9 2006-02-12 devnull return raddr;
807 5cdb1798 2005-10-29 devnull }
808 5cdb1798 2005-10-29 devnull
809 cbeb0b26 2006-04-01 devnull /* create a file and */
810 cbeb0b26 2006-04-01 devnull /* 1) ensure the modes we asked for */
811 cbeb0b26 2006-04-01 devnull /* 2) make gid == uid */
812 5cdb1798 2005-10-29 devnull static int
813 5cdb1798 2005-10-29 devnull docreate(char *file, int perm)
814 5cdb1798 2005-10-29 devnull {
815 5cdb1798 2005-10-29 devnull int fd;
816 5cdb1798 2005-10-29 devnull Dir ndir;
817 5cdb1798 2005-10-29 devnull Dir *d;
818 5cdb1798 2005-10-29 devnull
819 cbeb0b26 2006-04-01 devnull /* create the mbox */
820 5cdb1798 2005-10-29 devnull fd = create(file, OREAD, perm);
821 5cdb1798 2005-10-29 devnull if(fd < 0){
822 5cdb1798 2005-10-29 devnull fprint(2, "couldn't create %s\n", file);
823 5cdb1798 2005-10-29 devnull return -1;
824 5cdb1798 2005-10-29 devnull }
825 5cdb1798 2005-10-29 devnull d = dirfstat(fd);
826 5cdb1798 2005-10-29 devnull if(d == nil){
827 5cdb1798 2005-10-29 devnull fprint(2, "couldn't stat %s\n", file);
828 5cdb1798 2005-10-29 devnull return -1;
829 5cdb1798 2005-10-29 devnull }
830 5cdb1798 2005-10-29 devnull nulldir(&ndir);
831 5cdb1798 2005-10-29 devnull ndir.mode = perm;
832 5cdb1798 2005-10-29 devnull ndir.gid = d->uid;
833 5cdb1798 2005-10-29 devnull if(dirfwstat(fd, &ndir) < 0)
834 5cdb1798 2005-10-29 devnull fprint(2, "couldn't chmod %s: %r\n", file);
835 5cdb1798 2005-10-29 devnull close(fd);
836 5cdb1798 2005-10-29 devnull return 0;
837 5cdb1798 2005-10-29 devnull }
838 5cdb1798 2005-10-29 devnull
839 cbeb0b26 2006-04-01 devnull /* create a mailbox */
840 5cdb1798 2005-10-29 devnull int
841 5cdb1798 2005-10-29 devnull creatembox(char *user, char *folder)
842 5cdb1798 2005-10-29 devnull {
843 5cdb1798 2005-10-29 devnull char *p;
844 5cdb1798 2005-10-29 devnull String *mailfile;
845 5cdb1798 2005-10-29 devnull char buf[512];
846 5cdb1798 2005-10-29 devnull Mlock *ml;
847 5cdb1798 2005-10-29 devnull
848 5cdb1798 2005-10-29 devnull mailfile = s_new();
849 5cdb1798 2005-10-29 devnull if(folder == 0)
850 5cdb1798 2005-10-29 devnull mboxname(user, mailfile);
851 5cdb1798 2005-10-29 devnull else {
852 5cdb1798 2005-10-29 devnull snprint(buf, sizeof(buf), "%s/mbox", folder);
853 5cdb1798 2005-10-29 devnull mboxpath(buf, user, mailfile, 0);
854 5cdb1798 2005-10-29 devnull }
855 5cdb1798 2005-10-29 devnull
856 cbeb0b26 2006-04-01 devnull /* don't destroy existing mailbox */
857 5cdb1798 2005-10-29 devnull if(access(s_to_c(mailfile), 0) == 0){
858 5cdb1798 2005-10-29 devnull fprint(2, "mailbox already exists\n");
859 5cdb1798 2005-10-29 devnull return -1;
860 5cdb1798 2005-10-29 devnull }
861 5cdb1798 2005-10-29 devnull fprint(2, "creating new mbox: %s\n", s_to_c(mailfile));
862 5cdb1798 2005-10-29 devnull
863 cbeb0b26 2006-04-01 devnull /* make sure preceding levels exist */
864 5cdb1798 2005-10-29 devnull for(p = s_to_c(mailfile); p; p++) {
865 5cdb1798 2005-10-29 devnull if(*p == '/') /* skip leading or consecutive slashes */
866 5cdb1798 2005-10-29 devnull continue;
867 5cdb1798 2005-10-29 devnull p = strchr(p, '/');
868 5cdb1798 2005-10-29 devnull if(p == 0)
869 5cdb1798 2005-10-29 devnull break;
870 5cdb1798 2005-10-29 devnull *p = 0;
871 5cdb1798 2005-10-29 devnull if(access(s_to_c(mailfile), 0) != 0){
872 5cdb1798 2005-10-29 devnull if(docreate(s_to_c(mailfile), DMDIR|0711) < 0)
873 5cdb1798 2005-10-29 devnull return -1;
874 5cdb1798 2005-10-29 devnull }
875 5cdb1798 2005-10-29 devnull *p = '/';
876 5cdb1798 2005-10-29 devnull }
877 5cdb1798 2005-10-29 devnull
878 cbeb0b26 2006-04-01 devnull /* create the mbox */
879 5cdb1798 2005-10-29 devnull if(docreate(s_to_c(mailfile), 0622|DMAPPEND|DMEXCL) < 0)
880 5cdb1798 2005-10-29 devnull return -1;
881 5cdb1798 2005-10-29 devnull
882 5cdb1798 2005-10-29 devnull /*
883 5cdb1798 2005-10-29 devnull * create the lock file if it doesn't exist
884 5cdb1798 2005-10-29 devnull */
885 5cdb1798 2005-10-29 devnull ml = trylock(s_to_c(mailfile));
886 5cdb1798 2005-10-29 devnull if(ml != nil)
887 5cdb1798 2005-10-29 devnull sysunlock(ml);
888 5cdb1798 2005-10-29 devnull
889 5cdb1798 2005-10-29 devnull return 0;
890 5cdb1798 2005-10-29 devnull }