1 /* mkproto - make an mkfs prototype Author: Andrew Cagney */
3 /* Submitted by: cagney@chook.ua.oz (Andrew Cagney - aka Noid) */
14 /* The default values for the prototype file */
15 #define DEF_UID 2 /* bin */
16 #define DEF_GID 1 /* daemon group */
17 #define DEF_PROT 0555 /* a=re */
18 #define DEF_BLOCKS 360
20 #define DEF_INDENTSTR "\t"
23 #define major(x) ( (x>>8) & 0377)
24 #define minor(x) (x & 0377)
28 int count
, origlen
, tabs
;
29 int gid
, uid
, prot
, same_uid
, same_gid
, same_prot
, blocks
, inodes
;
30 int block_given
, inode_given
, dprot
;
32 char *proto_file
, *top
;
38 _PROTOTYPE(int main
, (int argc
, char **argv
));
39 _PROTOTYPE(void descend
, (char *dirname
));
40 _PROTOTYPE(void display_attrib
, (char *name
, struct stat
*st
));
41 _PROTOTYPE(void usage
, (char *binname
));
42 _PROTOTYPE(void open_outfile
, (void));
57 indentstr
= DEF_INDENTSTR
;
64 while ((op
= getopt(argc
, argv
, "b:g:i:p:t:u:d:s")) != EOF
) {
67 blocks
= atoi(optarg
);
72 if (gid
== 0) usage(argv
[0]);
76 inodes
= atoi(optarg
);
80 sscanf(optarg
, "%o", &prot
);
81 if (prot
== 0) usage(argv
[0]);
89 case 't': top
= optarg
; break;
92 if (uid
== 0) usage(argv
[0]);
95 case 'd': indentstr
= optarg
; break;
96 default: /* Illegal options */
101 if (optind
>= argc
) {
106 proto_file
= argv
[optind
];
110 if (block_given
&& !inode_given
) inodes
= (blocks
/ 3) + 8;
111 if (!block_given
&& inode_given
) usage(argv
[0]);
114 origlen
= strlen(dir
);
116 /* Check that it really is a directory */
118 if ((st
.st_mode
& S_IFMT
) != S_IFDIR
) {
119 fprintf(stderr
, "mkproto: %s must be a directory\n", dir
);
122 fprintf(outfile
, "boot\n%d %d\n", blocks
, inodes
);
123 display_attrib("", &st
);
124 fprintf(outfile
, "\n");
126 fprintf(outfile
, "$\n");
130 /* Output the prototype spec for this directory. */
131 void descend(dirname
)
136 char *name
, *temp
, *tempend
;
141 dirp
= opendir(dirname
);
143 fprintf(stderr
, "unable to open directory %s\n", dirname
);
147 temp
= (char *) malloc(sizeof(char) * strlen(dirname
) +1 + PATH_MAX
);
148 strcpy(temp
, dirname
);
150 tempend
= &temp
[strlen(temp
)];
152 for (dp
= readdir(dirp
); dp
!= NULL
; dp
= readdir(dirp
)) {
156 strcpy(tempend
, name
);
158 if (stat(temp
, &st
) == -1) {
159 fprintf(stderr
, "cant get status of '%s' \n", temp
);
162 if (name
[0] == '.' && (name
[1] == 0 ||
163 (name
[1] == '.' && name
[2] == 0)))
166 display_attrib(name
, &st
);
168 mode
= st
.st_mode
& S_IFMT
;
169 if (mode
== S_IFDIR
) {
170 fprintf(outfile
, "\n");
172 for (i
= 0; i
< tabs
; i
++) {
173 fprintf(outfile
, indentstr
);
175 fprintf(outfile
, "$\n");
178 if (mode
== S_IFBLK
|| mode
== S_IFCHR
) {
179 fprintf(outfile
, " %d %d\n", major(st
.st_rdev
), minor(st
.st_rdev
));
182 if (mode
== S_IFREG
) {
184 fprintf(outfile
, "%s%s", indentstr
, top
);
185 while (temp
[i
] != '\0') {
186 fputc(temp
[i
], outfile
);
189 fprintf(outfile
, "\n");
192 fprintf(outfile
, " /dev/null");
193 fprintf(stderr
,"File\n\t%s\n has an invalid mode, made empty.\n",temp
);
201 void display_attrib(name
, st
)
205 /* Output the specification for a single file */
209 if (same_uid
) uid
= st
->st_uid
;
210 if (same_gid
) gid
= st
->st_gid
;
212 prot
= st
->st_mode
& 0777; /***** This one is a bit shady *****/
213 for (i
= 0; i
< tabs
; i
++) fprintf(outfile
, indentstr
);
214 fprintf(outfile
, "%s%s%c%c%c%3o %d %d",
216 *name
== '\0' ? "" : indentstr
, /* stop the tab for a null name */
217 (st
->st_mode
& S_IFMT
) == S_IFDIR
? 'd' :
218 (st
->st_mode
& S_IFMT
) == S_IFCHR
? 'c' :
219 (st
->st_mode
& S_IFMT
) == S_IFBLK
? 'b' :
221 (st
->st_mode
& S_ISUID
) ? 'u' : '-', /* set uid */
222 (st
->st_mode
& S_ISGID
) ? 'g' : '-', /* set gid */
231 fprintf(stderr
, "Usage: %s [options] source_directory [prototype_file]\n", binname
);
232 fprintf(stderr
, "options:\n");
233 fprintf(stderr
, " -b n\t\t file system size is n blocks (default %d)\n", DEF_BLOCKS
);
234 fprintf(stderr
, " -d STRING\t define the indentation characters (default %s)\n", "(none)");
235 fprintf(stderr
, " -g n\t\t use n as the gid on all files (default %d)\n", DEF_GID
);
236 fprintf(stderr
, " -i n\t\t file system gets n i-nodes (default %d)\n", DEF_INODES
);
237 fprintf(stderr
, " -p nnn\t use nnn (octal) as mode on all files (default %o)\n", DEF_PROT
);
238 fprintf(stderr
, " -s \t\t use the same uid, gid and mode as originals have\n");
239 fprintf(stderr
, " -t ROOT\t inital path prefix for each entry\n");
240 fprintf(stderr
, " -u n\t\t use nnn as the uid on all files (default %d)\n", DEF_UID
);
246 if (proto_file
== NULL
)
248 else if ((outfile
= fopen(proto_file
, "w")) == NULL
)
249 fprintf(stderr
, "Cannot create %s\n ", proto_file
);