ref: cbe4b116989c0bfec49b9ae7a1d9a85ead6648ae
dir: /sys/src/cmd/unlnfs.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <libsec.h> enum { ENCLEN = 26, }; typedef struct Name Name; struct Name { char shortname[ENCLEN + 1]; char* longname; Name* next; }; Name *names; void rename(char*, char*, char*); void renamedir(char*); void readnames(char*); void main(int argc, char **argv) { char lnfile[256], *d; d = "."; if(argc > 1) d = argv[1]; snprint(lnfile, sizeof(lnfile), "%s/.longnames", d); readnames(lnfile); renamedir(d); } void renamedir(char *d) { int n; Dir *dir; char *sub; int fd, i; Name *na; fd = open(d, OREAD); if (fd == -1) return; while((n = dirread(fd, &dir)) > 0){ for(i = 0; i < n; i++){ if(dir[i].mode & DMDIR){ sub = malloc(strlen(d) + 1 + strlen(dir[i].name) + 1); sprint(sub, "%s/%s", d, dir[i].name); renamedir(sub); free(sub); } if(strlen(dir[i].name) != ENCLEN) continue; for (na = names; na != nil; na = na->next){ if (strcmp(na->shortname, dir[i].name) == 0){ rename(d, dir[i].name, na->longname); break; } } } free(dir); } close(fd); } void rename(char *d, char *old, char *new) { char *p; Dir dir; p = malloc(strlen(d) + 1 + strlen(old) + 1); sprint(p, "%s/%s", d, old); nulldir(&dir); dir.name = new; if(dirwstat(p, &dir) == -1) fprint(2, "unlnfs: cannot rename %s to %s: %r\n", p, new); free(p); } void long2short(char shortname[ENCLEN+1], char *longname) { uchar digest[MD5dlen]; md5((uchar*)longname, strlen(longname), digest, nil); enc32(shortname, ENCLEN+1, digest, MD5dlen); } void readnames(char *lnfile) { Biobuf *bio; char *f; Name *n; bio = Bopen(lnfile, OREAD); if(bio == nil){ fprint(2, "unlnfs: cannot open %s: %r\n", lnfile); exits("error"); } while((f = Brdstr(bio, '\n', 1)) != nil){ n = malloc(sizeof(Name)); n->longname = f; long2short(n->shortname, f); n->next = names; names = n; } Bterm(bio); }