9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: Russ Cox <rsc@swtch.com>
To: ISHWAR RATTAN <rattan@cps.cmich.edu>
Cc: Fans of the OS Plan 9 from Bell Labs <9fans@cse.psu.edu>
Subject: Re: [9fans] deleting files?
Date: Fri, 23 Sep 2005 12:13:25 -0400	[thread overview]
Message-ID: <ee9e417a050923091375aed85c@mail.gmail.com> (raw)
In-Reply-To: <Pine.GSO.4.61.0509231142420.2660@cps210.cps.cmich.edu.>

>    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);
}


      reply	other threads:[~2005-09-23 16:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-22 14:17 ISHWAR RATTAN
2005-09-22 14:21 ` Russ Cox
2005-09-23 15:43   ` ISHWAR RATTAN
2005-09-23 16:13     ` Russ Cox [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ee9e417a050923091375aed85c@mail.gmail.com \
    --to=rsc@swtch.com \
    --cc=9fans@cse.psu.edu \
    --cc=rattan@cps.cmich.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).