1 /* This program is free software. It comes without any warranty, to
2 * the extent permitted by applicable law. You can redistribute it
3 * and/or modify it under the terms of the Do What The Fuck You Want
4 * To Public License, Version 2, as published by Sam Hocevar. See
5 * http://sam.zoy.org/wtfpl/COPYING for more details. */
10 #define __USE_XOPEN_EXTENDED
24 static char *randstr(size_t len
) {
25 const char *chars
= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
30 name
= emalloc(len
+1);
32 for (i
= 0; i
< len
; i
++) {
33 name
[i
] = chars
[rand() % strlen(chars
)];
40 static char *randren(const char *path
) {
41 unsigned long newpathlen
= 0;
42 unsigned int error
= 0;
44 char *dname
, *rname
, *pathcopy
, *newpath
;
46 /* glibc dirname modifies its argument */
47 pathcopy
= strdup(path
);
49 dname
= dirname(pathcopy
);
51 /* Calling pathconf directly on a symlink will return the value for
52 * the file that it links to or, if it's a dangling symlink, -1
53 * (failure) so we use the directory it's stored in instead. */
54 rname
= randstr(pathconf(dname
, _PC_NAME_MAX
));
56 newpathlen
+= strlen(dname
);
57 newpathlen
+= strlen(rname
);
58 newpathlen
+= 2; /* '/' & '\0' */
60 newpath
= emalloc(newpathlen
);
62 strcpy(newpath
, dname
);
63 strcpy(newpath
+ strlen(newpath
), "/");
64 strcpy(newpath
+ strlen(newpath
), rname
);
65 strcpy(newpath
+ strlen(newpath
), "\0");
67 /* check whether the file exists */
68 if (access(newpath
, F_OK
) == 0) {
69 warnx("randren: File exists");
72 if (rename(path
, newpath
) == -1) {
89 static int fzero(const char *path
) {
96 if (stat(path
, &stbuf
) == -1) {
101 buf
= emalloc(stbuf
.st_blksize
);
103 if ((fd
= open(path
, O_WRONLY
)) == -1) {
108 while (written
< stbuf
.st_size
) {
109 written
+= write(fd
, buf
, stbuf
.st_blksize
);
120 int can_write(const struct stat
*sb
) {
124 if (sb
->st_uid
== id
) {
131 int fn(const char *fpath
, const struct stat
*sb
, int typeflag
,
132 struct FTW
*ftwbuf
) {
135 if (!can_write(sb
)) {
139 path
= randren(fpath
);
149 if (fzero(path
) != -1) {
162 int main(int argc
, char *argv
[]) {
165 while ((c
= getopt(argc
, argv
, "+v")) != -1) {
173 if (optind
== argc
) {
174 fprintf(stderr
, "usage: %s [-rv] [file ...]\n", argv
[0]);
180 for (i
= optind
; i
< argc
; i
++) {
181 nftw(argv
[i
], fn
, 10, FTW_DEPTH
| FTW_PHYS
);