the lnfs(4) man page refers to unlnfs, but it doesn't appear to be distributed. i've included a version i wrote in case you haven't got it. (i don't know whether the version referred to was mine, as i vaguely recall posting it, or someone else's. it's trivial anyway). Reference: /n/sources/patch/applied/unlnfs Date: Thu Feb 3 13:57:39 CET 2005 --- /sys/src/cmd/unlnfs.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/unlnfs.c Thu Feb 3 13:57:39 2005 @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +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; + uchar digest[MD5dlen]; + 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; + int slot; + 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); +}