generic/574: fix sporadic failure with test_dummy_encryption
[xfstests-dev.git] / src / t_create_long_dirs.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2009 FUJITSU LIMITED
4  * Author: Li Zefan <lizf@cn.fujitsu.com>
5  */
6
7 #define _POSIX_C_SOURCE 200809L
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include "config.h"
17
18 /* NCHARS = 10 + 26 + 26 = 62 */
19 #define NAME_LEN       255
20 #define NCHARS         62
21 #define MAX_LEN1       62
22 #define MAX_LEN2       (62 * 62)
23 #define MAX_LEN3       (62 * 62 * 62)
24
25 /* valid characters for the directory name */
26 char chars[NCHARS + 1] = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
27
28 /* to store the generated directory name */
29 char name[NAME_LEN + 1];
30 int names;
31 int parent_fd;
32
33 /*
34  * init_name - initialize the directory name
35  *
36  * Generate a randomized directory name, and then we generate more
37  * directory names based on it.
38  */
39 void init_name(void)
40 {
41        int i;
42
43        srand(time(NULL));
44
45        for (i = 0; i < NAME_LEN; i++)
46                name[i] = chars[rand() % 62];
47 }
48
49 void create_dir(void)
50 {
51        if (mkdirat(parent_fd, name, S_IRWXU)) {
52                perror("mkdir");
53                exit(1);
54        }
55 }
56
57 /*
58  * create_dirs - create @names directory names
59  * @n: how many names to be created
60  *
61  * if n <= 62,       we need to modify 1 char of the name
62  * if n <= 62*62,    we need to modify 2 chars
63  * if n <= 62*62*62, we need to modify 3 chars
64  */
65 void create_dirs(int n)
66 {
67        int i, j, k;
68        int depth;
69
70        if (n <= MAX_LEN1)
71                depth = 1;
72        else if (n <= MAX_LEN2)
73                depth = 2;
74        else
75                depth = 3;
76
77        for (i = 0; i < NCHARS; i++) {
78                name[0] = chars[i];
79                if (depth == 1) {
80                        create_dir();
81                        if (--n == 0)
82                                return;
83                        continue;
84                }
85
86                for (j = 0; j < NCHARS; j++) {
87                        name[1] = chars[j];
88                        if (depth == 2) {
89                                create_dir();
90                                if (--n == 0)
91                                        return;
92                                continue;
93                        }
94
95                        for (k = 0; k < NCHARS; k++) {
96                                name[2] = chars[k];
97                                create_dir();
98                                if (--n == 0)
99                                        return;
100                        }
101                }
102        }
103 }
104
105 void usage()
106 {
107        fprintf(stderr, "Usage: create_long_dirs nr_dirs parent_dir\n");
108 }
109
110 /*
111  * Create long-name directories
112  * @argv[1]: directory number
113  * @argv[2]: parent directory
114  */
115 int main(int argc, char *argv[])
116 {
117        if (argc != 3) {
118                usage();
119                return 1;
120        }
121
122        names = atoi(argv[1]);
123        if (names > MAX_LEN3 || names <= 0) {
124                usage();
125                return 1;
126        }
127
128        parent_fd = open(argv[2], O_RDONLY);
129        if (parent_fd == -1) {
130                perror("open parent dir failed");
131                return 1;
132        }
133
134        init_name();
135
136        create_dirs(names);
137
138        return 0;
139 }