chiark / gitweb /
Merge branches 'idx/verh' and 'idx/qmqpc'
[qmail] / qmail-getpw.c
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <pwd.h>
4 #include "readwrite.h"
5 #include "substdio.h"
6 #include "subfd.h"
7 #include "error.h"
8 #include "exit.h"
9 #include "byte.h"
10 #include "str.h"
11 #include "case.h"
12 #include "fmt.h"
13 #include "auto_usera.h"
14 #include "auto_break.h"
15 #include "qlx.h"
16
17 #define GETPW_USERLEN 32
18
19 char *local;
20 struct passwd *pw;
21 char *dash;
22 char *extension;
23
24 int userext()
25 {
26   char username[GETPW_USERLEN];
27   struct stat st;
28
29   extension = local + str_len(local);
30   for (;;) {
31     if (extension - local < sizeof(username))
32       if (!*extension || (*extension == *auto_break)) {
33         byte_copy(username,extension - local,local);
34         username[extension - local] = 0;
35         case_lowers(username);
36         errno = 0;
37         pw = getpwnam(username);
38         if (errno == error_txtbsy) _exit(QLX_SYS);
39         if (pw)
40           if (pw->pw_uid)
41             if (stat(pw->pw_dir,&st) == 0) {
42               if (st.st_uid == pw->pw_uid) {
43                 dash = "";
44                 if (*extension) { ++extension; dash = "-"; }
45                 return 1;
46               }
47             }
48             else
49               if (error_temp(errno)) _exit(QLX_NFS);
50       }
51     if (extension == local) return 0;
52     --extension;
53   }
54 }
55
56 char num[FMT_ULONG];
57
58 void main(argc,argv)
59 int argc;
60 char **argv;
61 {
62   local = argv[1];
63   if (!local) _exit(100);
64
65   if (!userext()) {
66     extension = local;
67     dash = "-";
68     pw = getpwnam(auto_usera);
69   }
70
71   if (!pw) _exit(QLX_NOALIAS);
72
73   substdio_puts(subfdoutsmall,pw->pw_name);
74   substdio_put(subfdoutsmall,"",1);
75   substdio_put(subfdoutsmall,num,fmt_ulong(num,(long) pw->pw_uid));
76   substdio_put(subfdoutsmall,"",1);
77   substdio_put(subfdoutsmall,num,fmt_ulong(num,(long) pw->pw_gid));
78   substdio_put(subfdoutsmall,"",1);
79   substdio_puts(subfdoutsmall,pw->pw_dir);
80   substdio_put(subfdoutsmall,"",1);
81   substdio_puts(subfdoutsmall,dash);
82   substdio_put(subfdoutsmall,"",1);
83   substdio_puts(subfdoutsmall,extension);
84   substdio_put(subfdoutsmall,"",1);
85   substdio_flush(subfdoutsmall);
86
87   _exit(0);
88 }