xref: /plan9/sys/src/cmd/unlnfs.c (revision 7545821f6f79b0dfcecb7f99982cb85e0b144a38)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <libsec.h>
5 
6 enum
7 {
8 	ENCLEN = 26,
9 };
10 
11 typedef struct Name Name;
12 struct Name {
13 	char	shortname[ENCLEN + 1];
14 	char*	longname;
15 	Name*	next;
16 };
17 
18 Name *names;
19 void rename(char*, char*, char*);
20 void renamedir(char*);
21 void readnames(char*);
22 
23 void
main(int argc,char ** argv)24 main(int argc, char **argv)
25 {
26 	char lnfile[256], *d;
27 	d = ".";
28 	if(argc > 1)
29 		d = argv[1];
30 
31 	snprint(lnfile, sizeof(lnfile), "%s/.longnames", d);
32 	readnames(lnfile);
33 	renamedir(d);
34 }
35 
36 void
renamedir(char * d)37 renamedir(char *d)
38 {
39 	int n;
40 	Dir *dir;
41 	char *sub;
42 	int fd, i;
43 	Name *na;
44 
45 	fd = open(d, OREAD);
46 	if (fd == -1)
47 		return;
48 	while((n = dirread(fd, &dir)) > 0){
49 		for(i = 0; i < n; i++){
50 			if(dir[i].mode & DMDIR){
51 				sub = malloc(strlen(d) + 1 + strlen(dir[i].name) + 1);
52 				sprint(sub, "%s/%s", d, dir[i].name);
53 				renamedir(sub);
54 				free(sub);
55 			}
56 			if(strlen(dir[i].name) != ENCLEN)
57 				continue;
58 			for (na = names; na != nil; na = na->next){
59 				if (strcmp(na->shortname, dir[i].name) == 0){
60 					rename(d, dir[i].name, na->longname);
61 					break;
62 				}
63 			}
64 		}
65 		free(dir);
66 	}
67 	close(fd);
68 }
69 
70 void
rename(char * d,char * old,char * new)71 rename(char *d, char *old, char *new)
72 {
73 	char *p;
74 	Dir dir;
75 	p = malloc(strlen(d) + 1 + strlen(old) + 1);
76 	sprint(p, "%s/%s", d, old);
77 	nulldir(&dir);
78 	dir.name = new;
79 	if(dirwstat(p, &dir) == -1)
80 		fprint(2, "unlnfs: cannot rename %s to %s: %r\n", p, new);
81 	free(p);
82 }
83 
84 void
long2short(char shortname[ENCLEN+1],char * longname)85 long2short(char shortname[ENCLEN+1], char *longname)
86 {
87 	uchar digest[MD5dlen];
88 	md5((uchar*)longname, strlen(longname), digest, nil);
89 	enc32(shortname, ENCLEN+1, digest, MD5dlen);
90 }
91 
92 void
readnames(char * lnfile)93 readnames(char *lnfile)
94 {
95 	Biobuf *bio;
96 	char *f;
97 	Name *n;
98 
99 	bio = Bopen(lnfile, OREAD);
100 	if(bio == nil){
101 		fprint(2, "unlnfs: cannot open %s: %r\n", lnfile);
102 		exits("error");
103 	}
104 	while((f = Brdstr(bio, '\n', 1)) != nil){
105 		n = malloc(sizeof(Name));
106 		n->longname = f;
107 		long2short(n->shortname, f);
108 		n->next = names;
109 		names = n;
110 	}
111 	Bterm(bio);
112 }
113