Commit | Line | Data |
---|---|---|
256cb8b6 | 1 | /*- |
097163c4 KB |
2 | * Copyright (c) 1989 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
256cb8b6 | 5 | * %sccs.include.redist.c% |
097163c4 KB |
6 | */ |
7 | ||
8 | #ifndef lint | |
78f31dbc | 9 | static char sccsid[] = "@(#)create.c 5.8 (Berkeley) %G%"; |
097163c4 KB |
10 | #endif /* not lint */ |
11 | ||
cbe4b98c | 12 | #include <sys/param.h> |
097163c4 | 13 | #include <sys/stat.h> |
256cb8b6 KB |
14 | #include <time.h> |
15 | #include <fts.h> | |
097163c4 | 16 | #include <dirent.h> |
256cb8b6 | 17 | #include <errno.h> |
097163c4 | 18 | #include <stdio.h> |
097163c4 KB |
19 | #include "mtree.h" |
20 | ||
256cb8b6 KB |
21 | #define LABEL \ |
22 | if (label++) \ | |
23 | (void)putchar(' '); \ | |
cbe4b98c | 24 | |
256cb8b6 KB |
25 | int ftsoptions = FTS_PHYSICAL; |
26 | ||
27 | cwalk() | |
cbe4b98c | 28 | { |
256cb8b6 KB |
29 | extern int dflag; |
30 | register FTS *t; | |
31 | register FTSENT *p; | |
32 | register int cnt, label, notset; | |
33 | time_t clock; | |
34 | uid_t uid; | |
35 | gid_t gid; | |
36 | mode_t mode; | |
37 | int tabs, dsort(); | |
38 | char curp[MAXPATHLEN], *inotype(), *getlogin(), *rlink(); | |
cbe4b98c KB |
39 | |
40 | if (!getwd(curp)) { | |
41 | (void)fprintf(stderr, "mtree: %s\n", curp); | |
42 | exit(1); | |
43 | } | |
44 | (void)time(&clock); | |
256cb8b6 | 45 | (void)printf("#\n#\t fs: %s\n#\t by: %s\n#\tdate: %s#\n", |
cbe4b98c KB |
46 | curp, getlogin(), ctime(&clock)); |
47 | ||
256cb8b6 KB |
48 | if (!(t = ftsopen(".", ftsoptions, dsort))) { |
49 | (void)fprintf(stderr, | |
50 | "mtree: ftsopen: %s.\n", strerror(errno)); | |
51 | exit(1); | |
097163c4 | 52 | } |
256cb8b6 KB |
53 | while (p = ftsread(t)) { |
54 | switch(p->fts_info) { | |
55 | case FTS_D: | |
56 | if (dflag) | |
57 | notset = 1; | |
58 | else | |
59 | notset = | |
60 | statdir(t, p, &uid, &gid, &mode, &tabs); | |
61 | if (!strcmp(p->fts_name, ".")) | |
62 | continue; | |
63 | break; | |
64 | case FTS_DC: | |
65 | (void)fprintf(stderr, | |
66 | "mtree: directory cycle: %s.\n", p->fts_path); | |
097163c4 | 67 | continue; |
256cb8b6 KB |
68 | case FTS_DNR: |
69 | (void)fprintf(stderr, | |
70 | "mtree: %s: unable to read.\n", p->fts_path); | |
71 | continue; | |
72 | case FTS_DNX: | |
73 | (void)fprintf(stderr, | |
74 | "mtree: %s: unable to search.\n", p->fts_path); | |
75 | continue; | |
76 | case FTS_DP: | |
77 | if (p->fts_level <= 0) | |
78 | continue; | |
79 | for (cnt = p->fts_level - 1; cnt-- > 0; ) | |
80 | (void)putchar('\t'); | |
81 | (void)printf("..\n"); | |
82 | continue; | |
83 | case FTS_ERR: | |
84 | (void)fprintf(stderr, "mtree: %s: %s.\n", | |
85 | p->fts_path, strerror(errno)); | |
86 | continue; | |
87 | case FTS_NS: | |
88 | (void)fprintf(stderr, | |
89 | "mtree: can't stat: %s.\n", p->fts_path); | |
097163c4 | 90 | continue; |
097163c4 | 91 | default: |
256cb8b6 KB |
92 | if (dflag) |
93 | continue; | |
097163c4 | 94 | } |
097163c4 | 95 | |
256cb8b6 KB |
96 | for (cnt = p->fts_level - 1; cnt-- > 0; ) |
97 | (void)putchar('\t'); | |
98 | (void)printf("%s", p->fts_name); | |
99 | if (p->fts_info == FTS_D) | |
100 | (void)putchar('\t'); | |
097163c4 | 101 | else { |
256cb8b6 KB |
102 | if (tabs > 1 && p->fts_namelen < 8) |
103 | (void)putchar('\t'); | |
104 | (void)putchar('\t'); | |
097163c4 | 105 | } |
cbe4b98c | 106 | |
097163c4 | 107 | label = 0; |
256cb8b6 | 108 | if (!S_ISREG(p->fts_statb.st_mode) || notset) { |
097163c4 | 109 | LABEL; |
256cb8b6 | 110 | (void)printf("type=%s", inotype(p->fts_statb.st_mode)); |
097163c4 | 111 | } |
256cb8b6 | 112 | if (p->fts_statb.st_uid != uid || notset) { |
097163c4 | 113 | LABEL; |
256cb8b6 | 114 | (void)printf("owner=%u", p->fts_statb.st_uid); |
097163c4 | 115 | } |
256cb8b6 | 116 | if (p->fts_statb.st_gid != gid || notset) { |
097163c4 | 117 | LABEL; |
256cb8b6 | 118 | (void)printf("group=%u", p->fts_statb.st_gid); |
097163c4 | 119 | } |
256cb8b6 KB |
120 | if ((p->fts_statb.st_mode & MBITS) != mode || notset) { |
121 | LABEL; | |
122 | (void)printf("mode=%#o", p->fts_statb.st_mode & MBITS); | |
123 | } | |
124 | if (p->fts_statb.st_nlink != 1 || notset) { | |
125 | LABEL; | |
126 | (void)printf("nlink=%u", p->fts_statb.st_nlink); | |
097163c4 KB |
127 | } |
128 | LABEL; | |
256cb8b6 KB |
129 | (void)printf("size=%ld", p->fts_statb.st_size); |
130 | ||
131 | if (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE) { | |
132 | LABEL; | |
133 | (void)printf("link=%s", rlink(p->fts_accpath)); | |
097163c4 | 134 | } |
256cb8b6 | 135 | (void)putchar('\n'); |
097163c4 KB |
136 | } |
137 | } | |
138 | ||
256cb8b6 KB |
139 | #define MAXGID 5000 |
140 | #define MAXUID 5000 | |
141 | #define MAXMODE 0777 + 1 | |
097163c4 | 142 | |
cbe4b98c | 143 | static |
256cb8b6 KB |
144 | statdir(t, parent, puid, pgid, pmode, tabs) |
145 | FTS *t; | |
146 | FTSENT *parent; | |
147 | uid_t *puid; | |
148 | gid_t *pgid; | |
149 | mode_t *pmode; | |
150 | int *tabs; | |
097163c4 | 151 | { |
256cb8b6 KB |
152 | register FTSENT *p; |
153 | register gid_t gid; | |
154 | register uid_t uid; | |
155 | register mode_t mode; | |
156 | gid_t savegid; | |
157 | uid_t saveuid; | |
158 | mode_t savemode; | |
159 | u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE]; | |
160 | ||
161 | if (!(p = ftschildren(t))) { | |
162 | if (errno) { | |
163 | (void)fprintf(stderr, "mtree: %s: %s.\n", | |
164 | RP(parent), strerror(errno)); | |
165 | exit(1); | |
097163c4 | 166 | } |
256cb8b6 KB |
167 | return(1); |
168 | } | |
169 | ||
170 | bzero(g, sizeof(g)); | |
171 | bzero(u, sizeof(u)); | |
172 | bzero(m, sizeof(m)); | |
173 | ||
174 | *tabs = 1; | |
175 | maxuid = maxgid = maxmode = 0; | |
176 | for (; p; p = p->fts_link) { | |
177 | mode = p->fts_statb.st_mode&0777; | |
178 | if (mode < MAXMODE && ++m[mode] > maxmode) { | |
179 | savemode = mode; | |
180 | maxmode = m[mode]; | |
181 | } | |
182 | gid = p->fts_statb.st_gid; | |
183 | if (gid < MAXGID && ++g[gid] > maxgid) { | |
184 | savegid = gid; | |
185 | maxgid = g[gid]; | |
186 | } | |
187 | uid = p->fts_statb.st_uid; | |
188 | if (uid < MAXUID && ++u[uid] > maxuid) { | |
189 | saveuid = uid; | |
190 | maxuid = u[uid]; | |
191 | } | |
192 | if (p->fts_namelen > 7) | |
193 | *tabs = 2; | |
194 | } | |
78f31dbc | 195 | (void)printf("\n/set group=%u mode=%#o nlink=1 owner=%u type=file\n", |
256cb8b6 KB |
196 | savegid, savemode, saveuid); |
197 | *puid = saveuid; | |
198 | *pgid = savegid; | |
199 | *pmode = savemode; | |
200 | return(0); | |
097163c4 KB |
201 | } |
202 | ||
cbe4b98c | 203 | static |
256cb8b6 KB |
204 | dsort(p1, p2) |
205 | FTSENT **p1, **p2; | |
097163c4 | 206 | { |
256cb8b6 | 207 | register FTSENT *a, *b; |
097163c4 | 208 | |
256cb8b6 KB |
209 | a = *p1; |
210 | b = *p2; | |
211 | ||
212 | if (S_ISDIR(a->fts_statb.st_mode)) { | |
213 | if (!S_ISDIR(b->fts_statb.st_mode)) | |
214 | return(1); | |
215 | } else if (S_ISDIR(b->fts_statb.st_mode)) | |
216 | return(-1); | |
217 | return(strcmp(a->fts_name, b->fts_name)); | |
097163c4 | 218 | } |