lint
[unix-history] / usr / src / usr.sbin / mtree / create.c
CommitLineData
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 9static 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
25int ftsoptions = FTS_PHYSICAL;
26
27cwalk()
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 143static
256cb8b6
KB
144statdir(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 203static
256cb8b6
KB
204dsort(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}