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