Introduction
Introduction Statistics Contact Development Disclaimer Help
xinstall.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
xinstall.c (3531B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <grp.h>
3 #include <pwd.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <dirent.h>
10 #include <sys/stat.h>
11 #include <sys/wait.h>
12
13 #include "util.h"
14
15 static int Dflag = 0;
16 static gid_t group;
17 static uid_t owner;
18 static mode_t mode = 0755;
19
20 static void
21 make_dir(char *dir, int was_missing)
22 {
23 if (!mkdir(dir, was_missing ? 0755 : mode)) {
24 if (!was_missing && (lchown(dir, owner, group) < 0))
25 eprintf("lchmod %s:", dir);
26 } else if (errno != EEXIST) {
27 eprintf("mkdir %s:", dir);
28 }
29 }
30
31 static void
32 make_dirs(char *dir, int was_missing)
33 {
34 char *p;
35 for (p = strchr(dir + (dir[0] == '/'), '/'); p; p = strchr(p + 1…
36 *p = '\0';
37 make_dir(dir, was_missing);
38 *p = '/';
39 }
40 make_dir(dir, was_missing);
41 }
42
43 static int
44 install(const char *s1, const char *s2, int depth)
45 {
46 int f1, f2;
47
48 if ((f1 = open(s1, O_RDONLY)) < 0)
49 eprintf("open %s:", s1);
50 if ((f2 = creat(s2, 0600)) < 0) {
51 if (unlink(s2) < 0 && errno != ENOENT)
52 eprintf("unlink %s:", s2);
53 if ((f2 = creat(s2, 0600)) < 0)
54 eprintf("creat %s:", s2);
55 }
56 if (concat(f1, s1, f2, s2) < 0)
57 goto fail;
58 if (fchmod(f2, mode) < 0) {
59 weprintf("fchmod %s:", s2);
60 goto fail;
61 }
62 if (fchown(f2, owner, group) < 0) {
63 weprintf("fchown %s:", s2);
64 goto fail;
65 }
66
67 close(f1);
68 close(f2);
69
70 return 0;
71
72 fail:
73 unlink(s2);
74 exit(1);
75 }
76
77 static void
78 usage(void)
79 {
80 eprintf("usage: %s [-g group] [-o owner] [-m mode] (-d dir ... |…
81 }
82
83 int
84 main(int argc, char *argv[])
85 {
86 int dflag = 0;
87 char *gflag = 0;
88 char *oflag = 0;
89 char *mflag = 0;
90 char *tflag = 0;
91 struct group *gr;
92 struct passwd *pw;
93 struct stat st;
94 char *p;
95
96 ARGBEGIN {
97 case 'c':
98 /* no-op for compatibility */
99 break;
100 case 'd':
101 dflag = 1;
102 break;
103 case 'D':
104 Dflag = 1;
105 break;
106 case 's':
107 /* no-op for compatibility */
108 break;
109 case 'g':
110 gflag = EARGF(usage());
111 break;
112 case 'o':
113 oflag = EARGF(usage());
114 break;
115 case 'm':
116 mflag = EARGF(usage());
117 break;
118 case 't':
119 tflag = EARGF(usage());
120 break;
121 default:
122 usage();
123 } ARGEND
124
125 if (argc < 1 + (!tflag & !dflag) || dflag & (Dflag | !!tflag))
126 usage();
127
128 if (gflag) {
129 errno = 0;
130 gr = getgrnam(gflag);
131 if (gr) {
132 group = gr->gr_gid;
133 } else {
134 if (errno)
135 eprintf("getgrnam %s:", gflag);
136 group = estrtonum(gflag, 0, UINT_MAX);
137 }
138 } else {
139 group = getgid();
140 }
141
142 if (oflag) {
143 errno = 0;
144 pw = getpwnam(oflag);
145 if (pw) {
146 owner = pw->pw_uid;
147 } else {
148 if (errno)
149 eprintf("getpwnam %s:", oflag);
150 owner = estrtonum(oflag, 0, UINT_MAX);
151 }
152 } else {
153 owner = getuid();
154 }
155
156 if (mflag)
157 mode = parsemode(mflag, mode, 0);
158
159 if (dflag) {
160 for (; *argv; argc--, argv++)
161 make_dirs(*argv, 0);
162 return 0;
163 }
164
165 if (tflag) {
166 argv = memmove(argv - 1, argv, argc * sizeof(*argv));
167 argv[argc++] = tflag;
168 }
169 if (tflag || argc > 2) {
170 if (stat(argv[argc - 1], &st) < 0) {
171 if ((errno == ENOENT) && Dflag) {
172 make_dirs(argv[argc - 1], 1);
173 } else {
174 eprintf("stat %s:", argv[argc - 1]);
175 }
176 } else if (!S_ISDIR(st.st_mode)) {
177 eprintf("%s: not a directory\n", argv[argc - 1]);
178 }
179 }
180 if (stat(argv[argc - 1], &st) < 0) {
181 if (errno != ENOENT)
182 eprintf("stat %s:", argv[argc - 1]);
183 if (tflag || Dflag || argc > 2) {
184 if ((p = strrchr(argv[argc - 1], '/')) != NULL) {
185 *p = '\0';
186 make_dirs(argv[argc - 1], 1);
187 *p = '/';
188 }
189 }
190 }
191 enmasse(argc, argv, install);
192
193 return 0;
194 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.