]>
Commit | Line | Data |
---|---|---|
cae5b340 AX |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License (the "License"). | |
6 | * You may not use this file except in compliance with the License. | |
7 | * | |
8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 | * or http://www.opensolaris.org/os/licensing. | |
10 | * See the License for the specific language governing permissions | |
11 | * and limitations under the License. | |
12 | * | |
13 | * When distributing Covered Code, include this CDDL HEADER in each | |
14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 | * If applicable, add the following below this CDDL HEADER, with the | |
16 | * fields enclosed by brackets "[]" replaced with your own identifying | |
17 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 | * | |
19 | * CDDL HEADER END | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | */ | |
26 | ||
27 | #include <errno.h> | |
28 | #include <stdio.h> | |
29 | #include <stdlib.h> | |
30 | #include <unistd.h> | |
31 | #include <string.h> | |
32 | #include <fcntl.h> | |
42f7b73b | 33 | #include <sys/xattr.h> |
cae5b340 AX |
34 | #include <sys/stat.h> |
35 | #include <sys/types.h> | |
36 | #include <sys/param.h> | |
37 | ||
38 | #define TYPE_D 'D' | |
39 | #define TYPE_F 'F' | |
40 | ||
41 | static char fdname[MAXPATHLEN] = {0}; | |
42 | static char *pbasedir = NULL; | |
43 | static int nlevel = 2; | |
44 | static int ndir = 2; | |
45 | static int nfile = 2; | |
46 | ||
47 | static void usage(char *this); | |
48 | static void crtfile(char *pname); | |
49 | static char *getfdname(char *pdir, char type, int level, int dir, int file); | |
50 | static int mktree(char *pbasedir, int level); | |
51 | ||
52 | int | |
53 | main(int argc, char *argv[]) | |
54 | { | |
55 | int c, ret; | |
56 | ||
57 | while ((c = getopt(argc, argv, "b:l:d:f:")) != -1) { | |
58 | switch (c) { | |
59 | case 'b': | |
60 | pbasedir = optarg; | |
61 | break; | |
62 | case 'l': | |
63 | nlevel = atoi(optarg); | |
64 | break; | |
65 | case 'd': | |
66 | ndir = atoi(optarg); | |
67 | break; | |
68 | case 'f': | |
69 | nfile = atoi(optarg); | |
70 | break; | |
71 | case '?': | |
72 | usage(argv[0]); | |
73 | } | |
74 | } | |
75 | if (nlevel < 0 || ndir < 0 || nfile < 0 || pbasedir == NULL) { | |
76 | usage(argv[0]); | |
77 | } | |
78 | ||
79 | ret = mktree(pbasedir, 1); | |
80 | ||
81 | return (ret); | |
82 | } | |
83 | ||
84 | static void | |
85 | usage(char *this) | |
86 | { | |
87 | (void) fprintf(stderr, | |
88 | "\tUsage: %s -b <base_dir> -l [nlevel] -d [ndir] -f [nfile]\n", | |
89 | this); | |
90 | exit(1); | |
91 | } | |
92 | ||
93 | static int | |
94 | mktree(char *pdir, int level) | |
95 | { | |
96 | int d, f; | |
97 | char dname[MAXPATHLEN] = {0}; | |
98 | char fname[MAXPATHLEN] = {0}; | |
99 | ||
100 | if (level > nlevel) { | |
101 | return (1); | |
102 | } | |
103 | ||
104 | for (d = 0; d < ndir; d++) { | |
105 | (void) memset(dname, '\0', sizeof (dname)); | |
106 | (void) strcpy(dname, getfdname(pdir, TYPE_D, level, d, 0)); | |
107 | ||
108 | if (mkdir(dname, 0777) != 0) { | |
109 | (void) fprintf(stderr, "mkdir(%s) failed." | |
110 | "\n[%d]: %s.\n", | |
111 | dname, errno, strerror(errno)); | |
112 | exit(errno); | |
113 | } | |
114 | ||
115 | /* | |
116 | * No sub-directory need be created, only create files in it. | |
117 | */ | |
118 | if (mktree(dname, level+1) != 0) { | |
119 | for (f = 0; f < nfile; f++) { | |
120 | (void) memset(fname, '\0', sizeof (fname)); | |
121 | (void) strcpy(fname, | |
122 | getfdname(dname, TYPE_F, level+1, d, f)); | |
123 | crtfile(fname); | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | for (f = 0; f < nfile; f++) { | |
129 | (void) memset(fname, '\0', sizeof (fname)); | |
130 | (void) strcpy(fname, getfdname(pdir, TYPE_F, level, d, f)); | |
131 | crtfile(fname); | |
132 | } | |
133 | ||
134 | return (0); | |
135 | } | |
136 | ||
137 | static char * | |
138 | getfdname(char *pdir, char type, int level, int dir, int file) | |
139 | { | |
42f7b73b AX |
140 | size_t size = sizeof (fdname); |
141 | if (snprintf(fdname, size, "%s/%c-l%dd%df%d", pdir, type, level, dir, | |
142 | file) >= size) { | |
143 | (void) fprintf(stderr, "fdname truncated\n"); | |
144 | exit(EINVAL); | |
145 | } | |
cae5b340 AX |
146 | return (fdname); |
147 | } | |
148 | ||
149 | static void | |
150 | crtfile(char *pname) | |
151 | { | |
152 | int fd = -1; | |
153 | int i, size; | |
154 | char *context = "0123456789ABCDF"; | |
155 | char *pbuf; | |
156 | ||
157 | if (pname == NULL) { | |
158 | exit(1); | |
159 | } | |
160 | ||
161 | size = sizeof (char) * 1024; | |
162 | pbuf = (char *)valloc(size); | |
163 | for (i = 0; i < size / strlen(context); i++) { | |
164 | int offset = i * strlen(context); | |
165 | (void) snprintf(pbuf+offset, size-offset, "%s", context); | |
166 | } | |
167 | ||
168 | if ((fd = open(pname, O_CREAT|O_RDWR, 0777)) < 0) { | |
169 | (void) fprintf(stderr, "open(%s, O_CREAT|O_RDWR, 0777) failed." | |
170 | "\n[%d]: %s.\n", pname, errno, strerror(errno)); | |
171 | exit(errno); | |
172 | } | |
173 | if (write(fd, pbuf, 1024) < 1024) { | |
174 | (void) fprintf(stderr, "write(fd, pbuf, 1024) failed." | |
175 | "\n[%d]: %s.\n", errno, strerror(errno)); | |
176 | exit(errno); | |
177 | } | |
178 | ||
179 | if (fsetxattr(fd, "user.xattr", pbuf, 1024, 0) < 0) { | |
180 | (void) fprintf(stderr, "fsetxattr(fd, \"xattr\", pbuf, " | |
181 | "1024, 0) failed.\n[%d]: %s.\n", errno, strerror(errno)); | |
182 | exit(errno); | |
183 | } | |
184 | ||
185 | (void) close(fd); | |
186 | free(pbuf); | |
187 | } |