* Re: [9fans] deleting files?
2005-09-23 15:43 ` ISHWAR RATTAN
@ 2005-09-23 16:13 ` Russ Cox
0 siblings, 0 replies; 4+ messages in thread
From: Russ Cox @ 2005-09-23 16:13 UTC (permalink / raw)
To: ISHWAR RATTAN; +Cc: Fans of the OS Plan 9 from Bell Labs
> The out put of
>
> ls | grep H.*test1.c | xd -b -c
> is
>
> 0000000 48 ef bf bd 74 65 73 74 31 2e 63 0a
> 0 H ef bf bd t e s t 1 . c \n
> 000000c
Bad UTF got into the file system some how,
and so ls is showing you an FFFD (RuneError) instead.
(Now I understand what you meant by [?].)
It looks like fossil doesn't check aggressively enough
to find bad UTF before using the name. We should fix
this, but until then, you can use the program below,
fixbadutf, to rename the troublesome files.
Russ
#include <u.h>
#include <libc.h>
void
usage(void)
{
fprint(2, "usage: fixbadutf [dir]\n");
exits("usage");
}
int
isbadutf(char *s)
{
Rune r;
int n;
r = Runeerror;
for(; *s; s+=n){
n = chartorune(&r, s);
if(r == Runeerror && n == 1)
return 1;
}
return 0;
}
char*
mkgoodname(char *name)
{
char *gname, *p, *s;
int i, n;
Rune r;
gname = malloc(strlen(name)+20);
if(gname == nil)
sysfatal("out of memory");
s = gname;
p = name;
for(; *p; p+=n){
n = chartorune(&r, p);
if(r == Runeerror && n == 1)
*s++ = '?';
else{
for(i=0; i<n; i++)
*s++ = p[i];
}
}
*s = 0;
for(i=0; i<100; i++){
if(access(gname, AEXIST) < 0)
return gname;
sprint(s, ".%d", i);
}
fprint(2, "cannot translate %s\n", name);
return nil;
}
void
main(int argc, char **argv)
{
char *dir, *errors, *newname, *oldname;
int fd, i, j, n;
Dir *d, xd;
ARGBEGIN{
default:
usage();
}ARGEND
if(argc > 1)
usage();
if(argc == 1)
dir = argv[0];
else
dir = ".";
if((fd = open(dir, OREAD)) < 0)
sysfatal("open %s: %r", dir);
errors = nil;
n = dirreadall(fd, &d);
for(i=0; i<n; i++){
if(isbadutf(d[i].name)){
oldname = malloc(strlen(dir)+1+strlen(d[i].name)+1);
if(oldname == nil)
sysfatal("out of memory");
strcpy(oldname, dir);
strcat(oldname, "/");
strcat(oldname, d[i].name);
newname = mkgoodname(d[i].name);
if(newname == nil)
continue;
nulldir(&xd);
xd.name = newname;
print("%s => %s\n", oldname, newname);
if(dirwstat(oldname, &xd) < 0){
fprint(2, "rename %s to %s: %r\n", oldname, newname);
errors = "errors";
}
free(oldname);
free(newname);
}
}
exits(errors);
}
^ permalink raw reply [flat|nested] 4+ messages in thread