1 /******************************************************************************/
2 /* */
3 /* Copyright (c) 2009 FUJITSU LIMITED */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation; either version 2 of the License, or */
8 /* (at your option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
13 /* the GNU General Public License for more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program; if not, write to the Free Software */
17 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18 /* */
19 /* Author: Li Zefan <lizf@cn.fujitsu.com> */
20 /* */
21 /******************************************************************************/
22
23 #define _ATFILE_SOURCE
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #include <fcntl.h>
30 #include <sys/types.h>
31 //#define __USE_ATFILE
32 #include <sys/stat.h>
33 #include "config.h"
34
35 #define NAME_LEN 255
36 #define NCHARS 62
37 #define MAX_LEN1 62
38 #define MAX_LEN2 (62 * 62)
39 #define MAX_LEN3 (62 * 62 * 62)
40
41 /* valid characters for the directory name */
42 char chars[NCHARS + 1] =
43 "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
44
45 /* to store the generated directory name */
46 char name[NAME_LEN + 1];
47 int names;
48 int parent_fd;
49
50 /*
51 * init_name - initialize the directory name
52 *
53 * Generate a randomized directory name, and then we generate more
54 * directory names based on it.
55 */
init_name(void)56 void init_name(void)
57 {
58 int i;
59
60 srand(time(NULL));
61
62 for (i = 0; i < NAME_LEN; i++)
63 name[i] = chars[rand() % 62];
64 }
65
create_dir(void)66 void create_dir(void)
67 {
68 #ifdef HAVE_MKDIRAT
69 if (mkdirat(parent_fd, name, S_IRWXU)) {
70 perror("mkdir");
71 exit(1);
72 }
73 #else
74 fprintf(stderr, "System lacks mkdirat() call.\n");
75 exit(1);
76 #endif
77 }
78
79 /*
80 * create_dirs - create @names directory names
81 * @n: how many names to be created
82 *
83 * if n <= 62, we need to modify 1 char of the name
84 * if n <= 62*62, we need to modify 2 chars
85 * if n <= 62*62*62, we need to modify 3 chars
86 */
create_dirs(int n)87 void create_dirs(int n)
88 {
89 int i, j, k;
90 int depth;
91
92 if (n <= MAX_LEN1)
93 depth = 1;
94 else if (n <= MAX_LEN2)
95 depth = 2;
96 else
97 depth = 3;
98
99 for (i = 0; i < NCHARS; i++) {
100 name[0] = chars[i];
101 if (depth == 1) {
102 create_dir();
103 if (--n == 0)
104 return;
105 continue;
106 }
107
108 for (j = 0; j < NCHARS; j++) {
109 name[1] = chars[j];
110 if (depth == 2) {
111 create_dir();
112 if (--n == 0)
113 return;
114 continue;
115 }
116
117 for (k = 0; k < NCHARS; k++) {
118 name[2] = chars[k];
119 create_dir();
120 if (--n == 0)
121 return;
122 }
123 }
124 }
125 }
126
usage()127 void usage()
128 {
129 fprintf(stderr, "Usage: create_long_dirs nr_dirs parent_dir\n");
130 }
131
132 /*
133 * Create long-name directories
134 * @argv[1]: directory number
135 * @argv[2]: parent directory
136 */
main(int argc,char * argv[])137 int main(int argc, char *argv[])
138 {
139 if (argc != 3) {
140 usage();
141 return 1;
142 }
143
144 names = atoi(argv[1]);
145 if (names > MAX_LEN3 || names <= 0) {
146 usage();
147 return 1;
148 }
149
150 parent_fd = open(argv[2], O_RDONLY);
151 if (parent_fd == -1) {
152 perror("open parent dir failed");
153 return 1;
154 }
155
156 init_name();
157
158 create_dirs(names);
159
160 return 0;
161 }
162