1 /*- 2 * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #include <sys/types.h> 29 #include <sys/sysctl.h> 30 #include <unistd.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <fcntl.h> 34 #include <sys/stat.h> 35 #include <sys/param.h> 36 #include <sys/errno.h> 37 #include <string.h> 38 #include <err.h> 39 40 41 static int files = 5; 42 static int fs = 1024; 43 static char *buffer; 44 static int max; 45 46 void 47 error(char *op, char* arg, char* file, int line) { 48 fprintf(stderr,"%s. %s. %s (%s:%d)\n", 49 op, arg, sys_errlist[errno], file, line); 50 } 51 52 void 53 mkDir(char *path, int level) { 54 int fd, j; 55 char newPath[MAXPATHLEN + 1]; 56 char file[128]; 57 58 if (mkdir(path, 0770) == -1) { 59 error("mkdir", path, __FILE__, __LINE__); 60 fprintf(stderr, "length(path) = %d\n", strlen(path)); 61 fprintf(stderr, ") level = %d\n", level); 62 exit(2); 63 } 64 chdir(path); 65 66 for (j = 0; j < files; j++) { 67 sprintf(file,"f%05d", j); 68 if ((fd = creat(file, 0660)) == -1) { 69 if (errno != EINTR) { 70 err(1, "%d: creat(%s)", level, file); 71 break; 72 } 73 } 74 if (write(fd, buffer, fs) != fs) 75 err(1, "%d: write(%s), %s:%d", level, file, __FILE__, __LINE__); 76 77 if (fd != -1 && close(fd) == -1) 78 err(2, "%d: close(%d)", level, j); 79 80 } 81 82 if (level < max) { 83 sprintf(newPath,"d%d", level+1); 84 mkDir(newPath, level+1); 85 } 86 } 87 88 static void 89 rmFile(void) 90 { 91 int j; 92 char file[128]; 93 94 for (j = 0; j < files; j++) { 95 sprintf(file,"f%05d", j); 96 (void) unlink(file); 97 } 98 } 99 100 void 101 rmDir(char *path, int level) { 102 char newPath[10]; 103 104 105 if (level < max) { 106 sprintf(newPath,"d%d", level+1); 107 rmDir(newPath, level+1); 108 } 109 rmFile(); 110 chdir (".."); 111 if (rmdir(path) == -1) { 112 error("rmdir", path, __FILE__, __LINE__); 113 exit(2); 114 } 115 } 116 117 void 118 rmDir2(char *path, int level) { 119 char newPath[10]; 120 char help[80]; 121 122 rmFile(); 123 chdir(path); 124 sprintf(newPath,"d%d", level+1); 125 if (access(newPath, R_OK) == 0) 126 rmDir2(newPath, level+1); 127 chdir (".."); 128 if (rmdir(path) == -1) { 129 error("rmdir", path, __FILE__, __LINE__); 130 sprintf(help, "rm -rf ./%s", path); 131 system(help); 132 } 133 } 134 135 int 136 main(int argc, char **argv) 137 { 138 int c, levels = 1, leave = 0; 139 char path[128], rpath[128] = ""; 140 char ch = 0; 141 extern char *optarg; 142 pid_t pid; 143 144 while ((c = getopt(argc, argv, "ln:r:f:s:")) != -1) 145 switch (c) { 146 case 'l': 147 leave = 1; 148 break; 149 case 'r': 150 strcpy(rpath, optarg); 151 break; 152 case 'n': 153 levels = atoi(optarg); 154 break; 155 case 'f': 156 files = atoi(optarg); 157 break; 158 case 's': 159 sscanf(optarg, "%d%c", &fs, &ch); 160 if (ch == 'k' || ch == 'K') 161 fs = fs * 1024; 162 if (ch == 'm' || ch == 'M') 163 fs = fs * 1024 * 1024; 164 break; 165 default: 166 fprintf(stderr, 167 "Usage: %s {-l} | {-n <num>} | -r <dir> | -s <file size> " 168 "-f <num>\n", 169 argv[0]); 170 printf(" -l: Leave the files.\n"); 171 printf(" -r: Remove an old tree.\n"); 172 printf(" -n: Tree depth.\n"); 173 printf(" -f: Number of files.\n"); 174 printf(" -s: Size of each file.\n"); 175 exit(1); 176 } 177 178 179 max = levels; 180 pid = getpid(); 181 if ((buffer = calloc(1, fs)) == NULL) 182 err(1, "calloc(%d)", fs); 183 184 if (strlen(rpath) > 0) { 185 rmDir2(rpath,1); 186 } else { 187 umask(0); 188 sprintf(path,"p%05d.d%d", pid, 1); 189 mkDir(path, 1); 190 if (leave == 0) rmDir(path, 1); 191 } 192 return 0; 193 } 194