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