4 #define __USE_XOPEN_EXTENDED
18 static char *randstr(size_t len
) {
19 const char *chars
= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
24 name
= emalloc(len
+1);
26 for (i
= 0; i
< len
; i
++) {
27 name
[i
] = chars
[rand() % strlen(chars
)];
34 static char *randren(const char *path
) {
35 unsigned long newpathlen
= 0;
36 unsigned int error
= 0;
38 char *dname
, *rname
, *pathcopy
, *newpath
;
40 /* glibc dirname modifies its argument */
41 pathcopy
= strdup(path
);
43 dname
= dirname(pathcopy
);
45 /* Calling pathconf directly on a symlink will return the value for
46 * the file that it links to or, if it's a dangling symlink, -1
47 * (failure) so we use the directory it's stored in instead. */
48 rname
= randstr(pathconf(dname
, _PC_NAME_MAX
));
50 newpathlen
+= strlen(dname
);
51 newpathlen
+= strlen(rname
);
52 newpathlen
+= 2; /* '/' & '\0' */
54 newpath
= emalloc(newpathlen
);
56 strcpy(newpath
, dname
);
57 strcpy(newpath
+ strlen(newpath
), "/");
58 strcpy(newpath
+ strlen(newpath
), rname
);
59 strcpy(newpath
+ strlen(newpath
), "\0");
61 /* check whether the file exists */
62 if (access(newpath
, F_OK
) == 0) {
63 warnx("randren: File exists");
66 if (rename(path
, newpath
) == -1) {
83 static int fzero(const char *path
) {
90 if (stat(path
, &stbuf
) == -1) {
95 buf
= emalloc(stbuf
.st_blksize
);
97 if ((fd
= open(path
, O_WRONLY
)) == -1) {
102 while (written
< stbuf
.st_size
) {
103 written
+= write(fd
, buf
, stbuf
.st_blksize
);
114 int can_write(const struct stat
*sb
) {
118 if (sb
->st_uid
== id
) {
125 int fn(const char *fpath
, const struct stat
*sb
, int typeflag
,
126 struct FTW
*ftwbuf
) {
129 if (!can_write(sb
)) {
133 path
= randren(fpath
);
143 if (fzero(path
) != -1) {
156 int main(int argc
, char *argv
[]) {
159 while ((c
= getopt(argc
, argv
, "+v")) != -1) {
167 if (optind
== argc
) {
168 fprintf(stderr
, "usage: %s [-rv] [file ...]\n", argv
[0]);
174 for (i
= optind
; i
< argc
; i
++) {
175 nftw(argv
[i
], fn
, 10, FTW_DEPTH
| FTW_PHYS
);