summaryrefslogtreecommitdiff
path: root/src/t_create_long_dirs.c
blob: 0a7ee0fd4a58ba6e7bac0d2df296fddd81e60d1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2009 FUJITSU LIMITED
 * Author: Li Zefan <lizf@cn.fujitsu.com>
 */

#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "config.h"

/* NCHARS = 10 + 26 + 26 = 62 */
#define NAME_LEN       255
#define NCHARS         62
#define MAX_LEN1       62
#define MAX_LEN2       (62 * 62)
#define MAX_LEN3       (62 * 62 * 62)

/* valid characters for the directory name */
char chars[NCHARS + 1] = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";

/* to store the generated directory name */
char name[NAME_LEN + 1];
int names;
int parent_fd;

/*
 * init_name - initialize the directory name
 *
 * Generate a randomized directory name, and then we generate more
 * directory names based on it.
 */
void init_name(void)
{
       int i;

       srand(time(NULL));

       for (i = 0; i < NAME_LEN; i++)
               name[i] = chars[rand() % 62];
}

void create_dir(void)
{
       if (mkdirat(parent_fd, name, S_IRWXU)) {
               perror("mkdir");
               exit(1);
       }
}

/*
 * create_dirs - create @names directory names
 * @n: how many names to be created
 *
 * if n <= 62,       we need to modify 1 char of the name
 * if n <= 62*62,    we need to modify 2 chars
 * if n <= 62*62*62, we need to modify 3 chars
 */
void create_dirs(int n)
{
       int i, j, k;
       int depth;

       if (n <= MAX_LEN1)
               depth = 1;
       else if (n <= MAX_LEN2)
               depth = 2;
       else
               depth = 3;

       for (i = 0; i < NCHARS; i++) {
               name[0] = chars[i];
               if (depth == 1) {
                       create_dir();
                       if (--n == 0)
                               return;
                       continue;
               }

               for (j = 0; j < NCHARS; j++) {
                       name[1] = chars[j];
                       if (depth == 2) {
                               create_dir();
                               if (--n == 0)
                                       return;
                               continue;
                       }

                       for (k = 0; k < NCHARS; k++) {
                               name[2] = chars[k];
                               create_dir();
                               if (--n == 0)
                                       return;
                       }
               }
       }
}

void usage()
{
       fprintf(stderr, "Usage: create_long_dirs nr_dirs parent_dir\n");
}

/*
 * Create long-name directories
 * @argv[1]: directory number
 * @argv[2]: parent directory
 */
int main(int argc, char *argv[])
{
       if (argc != 3) {
               usage();
               return 1;
       }

       names = atoi(argv[1]);
       if (names > MAX_LEN3 || names <= 0) {
               usage();
               return 1;
       }

       parent_fd = open(argv[2], O_RDONLY);
       if (parent_fd == -1) {
               perror("open parent dir failed");
               return 1;
       }

       init_name();

       create_dirs(names);

       return 0;
}