[comp.unix.xenix] Confused file name in directory

jim@aob.UUCP (02/23/87)

I have an Altos 2086 running XENIX 3.2f.  I had a problem show up recently
that defies all my attempts to fix.  What has happened is that a file name
in a directory has a null in the middle of the name.  The file is actually
the name of a directory.  The name used to be 'Doc', but is now 'D\0c'.
All the programs in the system now say 'D' is a bad file name.  Since I
can't seem to write in the directory, I can't change the null to something
else or get rid of the 'c' after the null.  Does anybody know how I can
get rid of this file name, or better yet, rename the file to a typable
name?  Fsck doesn't find anything wrong with the file, and I can't unlink
the file because unlink can't find 'D\0c'.
--
Jim Anderson			(612) 636-2869
Anderson O'Brien, Inc		New mail:jim@aob.uucp
2575 N. Fairview Ave.		Old mail:{rutgers,gatech,amdahl}!meccts!aob!jim
St. Paul, MN  55113		"Fireball... Let me see... How did that go?"

pdb@sei.cmu.edu.UUCP (02/25/87)

As a last resort you could use 'clri' on the inode associated with that
file (use 'ls -li' to find the inode numner).  fsck will certainly allow
you to clear the directory entry once it realizes the inode's been zeroed.

--Pat.

ssl@ptsfa.UUCP (02/25/87)

In article <563@aw.sei.cmu.edu.sei.cmu.edu> pdb@sei.cmu.edu (Patrick Barron) writes:
>
>As a last resort you could use 'clri' on the inode associated with that
>file (use 'ls -li' to find the inode numner).  fsck will certainly allow
>you to clear the directory entry once it realizes the inode's been zeroed.
>
>--Pat.

But as a last to the last resort, if you don't really want to get rid
of things, I'll try this before 'clri':
	1. make sure there's only one directory and/or filename start
	   with D
	2. then 'mv D* goodname'
Didn't try this with D\0a though, this might/might not work, but doesn't
hurt give it a try before earsing everything.  As long as D* expands into
one name, mv will work.


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Sam Lok		San Francisco		{ihnp4,pyramid,qantel}!ptsfa!ssl
				|| To err is human, to really foul things
Disclaimer!?  WHAT disclaimer?	|| up requires super-user privilege!

chris@mimsy.UUCP (02/25/87)

In article <105@aob.UUCP> someone finds a directory entry with an
embedded NUL, and has nothing handy to fix it.

In article <563@aw.sei.cmu.edu.sei.cmu.edu> pdb@sei.cmu.edu (Patrick
Barron) writes:
>As a last resort you could use 'clri' on the inode associated with that
>file (use 'ls -li' to find the inode numner).

This will indeed make fsck clear the directory entry, but will also
lose the contents of the file.  If there is another link to the
file, it can be copied first, but if not, there are other ways.

The problem is in the directory itself, not in the file; so you
can clri the directory inode, and fsck will put any orphaned files
in the lost+found directory.  This will lose the names of each of
the inodes, but these can be saved first:

	# ls -li <bad_dir> > dir_list
	# clri <inode>
	# umount <drive>
	# fsck <drive>
	# mount <drive>
	# cd <lost+found_area>
	# mkdir <bad_dir>
	# sh <script> <bad_dir> < dir_list

where `script' reads name/inode pairs out of a directory and `mv's
the file `#<inode>' (six digits) to $2/<name>.

Note that any files with other links will not be placed in lost+found,
and must be re-linked `by hand' later (after tracking them down
with ncheck).  Also, make sure there is enough directory space in
lost+found for all the files that will be orphaned, if necessary
by augmenting the mklost+found shell script.

There is still another way, easier yet but more dangerous and
thrilling.  You cannot edit a directory, but you can edit a file.
And the only difference between the two is one byte.

Using the source to clri, ---you say you have no source?  Ah well.
Perhaps if you ask nicely, your vendor will help.  I would not
count on it.  Source is better.  ---Using clri.c, or your magical
knowledge of file system formats, write another program, `hacki'.
Instead of zeroing the inode, toggle the S_IFDIR and S_IFREG bits.
Run it once on the directory inode, and now it is a file.  Use your
favourite binary editor (Emacs works, but be sure it does not make
a backup!), fix the embedded NUL character.  Make sure the file size
is exactly the same as before.  Then run the hacki program once
more.

(I did this once on a 4.1BSD system.  It worked quite well.)

Of course, if you have source, you could alter fsck to check for
embedded NULs in filenames.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

ron@brl-sem.UUCP (02/26/87)

In article <105@aob.UUCP>, jim@aob.UUCP (Jim Anderson) writes:
> name?  Fsck doesn't find anything wrong with the file, and I can't unlink
> the file because unlink can't find 'D\0c'.

ls -i will give the inode number.  Run clri on that inode and follow
it up with FSCK.  If you really want it back you can probably use dump
and restore to fish it out.

You could probably poke the block on the raw device, but this is likely
to be more trouble than it is worth.

-Ron

ron@brl-sem.UUCP (02/26/87)

In article <2136@ptsfa.UUCP>, ssl@ptsfa.UUCP (Sam Lok) writes:
> But as a last to the last resort, if you don't really want to get rid
> of things, I'll try this before 'clri':
> 	1. make sure there's only one directory and/or filename start
> 	   with D
> 	2. then 'mv D* goodname'

THIS WILL NOT WORK.

The problem is that the UNIX directory structure is exactly 14 characters
long and some older versions of UNIX (version 7 which XENIX is based on,
don't know if System V has the same problem) compare all the 14 characters
to do a match.  They expect all the unused characters to have nulls in them
rather than be null terminated.  There is NOTHING you can do through the
UNIX file system that will reference this file.  Think about it.  D*
would just expand to "D".  Mv knows nothing special about "*", that is
expanded by the  shell and passed as an argument to mv.  You still can't
pass that to unlink or open because the null terminates the string.

-Ron

guy@gorodish.UUCP (02/26/87)

>Of course, if you have source, you could alter fsck to check for
>embedded NULs in filenames.

And not to *generate* file names with embedded NULs.  Some versions
of "fsck" for the V7 file system (as used in most UNIX systems not
using the 4.2BSD file system) would assume that any free directory
slot in "lost+found" would have no non-NUL characters in the
directory name portion of that slot, which is not the case.  The V7
and System III versions did not zero out the entire file name; this
is fixed in S5.  Check the routine "mkentry".

matt@oddjob.UUCP (02/26/87)

In article <5587@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
) In article <105@aob.UUCP> someone finds a directory entry with an
) embedded NUL, and has nothing handy to fix it.
) 
) There is still another way, easier yet but more dangerous and
) thrilling.  You cannot edit a directory, but you can edit a file.
) And the only difference between the two is one byte.   ...

Hoowie!  Is that complicated.  Sounds fun though.  I just
unmount the partition, get out a calculator, and adb the raw
disk.

		Time to write "kmem.el" for emacs....
			   Matt

df@nud.UUCP (02/27/87)

In article <105@aob.UUCP> jim@aob.UUCP (Jim Anderson) writes:
>I have an Altos 2086 running XENIX 3.2f.  I had a problem show up recently
>that defies all my attempts to fix.  What has happened is that a file name
>in a directory has a null in the middle of the name.  The file is actually
>the name of a directory.  The name used to be 'Doc', but is now 'D\0c'.

I don't know how the null got into your directory entry in the first
place, but to fix it you will have to use fsdb or a similar tool to
change the name in the directory entry through a mechanism outside the
bounds of the normal file access system calls.

The kernel routine namei (which associates filenames to inodes) can be
blamed for making recovery difficult.  It takes the null terminated file
name that you pass it, adds additional nulls to the end to make it a
total of 14 bytes in length, then compares *all* 14 bytes with the name
in the directory entry.  This makes it impossible to match a directory
entry with a null embedded in the name.  (Of course, the null *can't*
possibly get there in the first place :-))

Namei works this way on System V up to and including System V.3.

-Dale

---
Dale Farnsworth (NO7K)			seismo!noao!mcdsun!nud!df
(602)438-5739				ihnp4!mot!nud!df

rlk@chinet.UUCP (02/27/87)

I've used the following to correct directory entries with unprintable
characters.  I don't know if it will work with the NULL.

	ls -i D*		to get the inode number
	find . -inum number -exec mv {} new_name \;

You might want to verify that the inode number is unique if you have
multiple filesystems, if they are subdirs of `.'


-- 
---
UUCP: ..!ihnp4!chinet!uklpl!rlk || MCIMail: rklappal || Compuserve: 74106,1021
      ..!ihnp4!ihu1h!rlk
---

simon@its63b.UUCP (02/27/87)

In article <5587@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <105@aob.UUCP> someone finds a directory entry with an
>embedded NUL, and has nothing handy to fix it.
>
>There is still another way, easier yet but more dangerous and
>thrilling.  You cannot edit a directory, but you can edit a file.
>And the only difference between the two is one byte.
>
>Write another program, `hacki'.
>Instead of zeroing the inode, toggle the S_IFDIR and S_IFREG bits.
>Run it once on the directory inode, and now it is a file.  Use your
>favourite binary editor (Emacs works, but be sure it does not make
>a backup!), fix the embedded NUL character.  Make sure the file size
>is exactly the same as before.  Then run the hacki program once
>more.
>
>Of course, if you have source, you could alter fsck to check for
>embedded NULs in filenames.

Another "entity" you can edit is a disk - using a nice powerful editor
like adb :-) So, just find the i-number for the directory, then: power-up
your adb, find the inode-entry for the directory, from which you can find the
data-block list (luckily there're hardly ever any indirect blocks in a 
directory, unless its very big), find the bad bytes, and change them to 
something sensible.

Why write new code when you do anything you need using existing utilities :-)

-- 

-----------------------------
Simon Brown                                             @@@\
Department of Computer Science                         /-/@ \
University of Edinburgh, Scotland, UK.                / /@   \@@
                                                     / /@     \-\
UUCP:  seismo!mcvax!ukc!{its63b,cstvax}!simon       / /@/-/    \ \
JANET: simon@uk.ac.ed.{its63b,cstvax}              / /@/ / /-/  \ \
ARPA:  simon@{its63b,cstvax}.ed.ac.uk             /-/@/-/ /-/    \ \
------------------------------                   ~~~~~~~~~~~~~~~~~~~~
                                             "Life's like that, you know"

spf@clyde.UUCP (02/27/87)

In article <5587@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <105@aob.UUCP> someone finds a directory entry with an
>embedded NUL, and has nothing handy to fix it.

I have a public-domain c program call rmfile which is interactive
and lets you either delete or rename files (including those with
garbage characters in their names).  I've never paid attention to
how it works, but I've used it and it DOES work.  It's about 246
lines of c source, and compiled on my PC6300 under XENIX V with no
trouble.  If there's interest, I'll post it to comp.sources or
something. Let me know if you want it.
Steve

terryl@tekcrl.UUCP (02/28/87)

In article <1667@oddjob.UChicago.EDU> matt@oddjob.uchicago.edu (Yes, *THAT* Matt Crawford) writes:
+In article <5587@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
+) In article <105@aob.UUCP> someone finds a directory entry with an
+) embedded NUL, and has nothing handy to fix it.
+) 
+) There is still another way, easier yet but more dangerous and
+) thrilling.  You cannot edit a directory, but you can edit a file.
+) And the only difference between the two is one byte.   ...
+
+Hoowie!  Is that complicated.  Sounds fun though.  I just
+unmount the partition, get out a calculator, and adb the raw
+disk.

     Any wizard worth his paycheck would take it one step further: adb the
block partition(don't have to unmount it first) and then use adb to modify
the ACTUAL directory block where the entry with the embedded NULL in it.
It's doable (I've done it on a V7 file system; I don't know if I'd want to
try it on a 4.2 file system). You wanna talk about complicated????

blm@cxsea.UUCP (02/28/87)

In article <105@aob.UUCP> jim@aob.UUCP (Jim Anderson) writes:
|I have an Altos 2086 running XENIX 3.2f.  I had a problem show up recently
|that defies all my attempts to fix.  What has happened is that a file name
|in a directory has a null in the middle of the name.

I'm not familiar with XENIX, but System V has a utility called fsdb, that
let's you do strange and wonderous things to a file system, one of which is
to modify the name field of a directory entry. fsdb has to be run on an
unmounted file system, probably as superuser (if the permissions are set
up the way they should be on the file systems device). In my manual, the
second to last example is setting a file name.

If XENIX doesn't have fsdb, I guess I can't help you. clri/fsck is probably
the only way to go.

-- 

Brian L. Matthews                               "Facts are impotent against
...{mnetor,uw-beaver!ssc-vax}!cxsea!blm          loud and frequent assertion."
+1 206 251 6811
Computer X Inc. - a division of Motorola New Enterprises

dave@onfcanim.UUCP (02/28/87)

>) There is still another way, easier yet but more dangerous and
>) thrilling.  You cannot edit a directory, but you can edit a file.
>) And the only difference between the two is one byte.   ...
>
>Hoowie!  Is that complicated.  Sounds fun though.  I just
>unmount the partition, get out a calculator, and adb the raw
>disk.

It's most easily done as a three-step process:

1) unmount the disk, figure out where that inode lives on the disk,
   adb disk and patch the inode's "format" word to make it into a plain file.

2) mount the disk (while single user!), and edit the directory with
   adb, emacs, whatever

3) unmount the disk, patch the inode back into a directory, fsck the
   filesystem unless you have a great deal of confidence in yourself,
   then bring the machine back up.

This minimizes the possibility of clobbering something other than
the directory you want to alter.

guy@gorodish.UUCP (03/01/87)

>>In article <105@aob.UUCP> someone finds a directory entry with an
>>embedded NUL, and has nothing handy to fix it.
>
>I have a public-domain c program call rmfile which is interactive
>and lets you either delete or rename files (including those with
>garbage characters in their names).  I've never paid attention to
>how it works, but I've used it and it DOES work.

Unless this program does so by opening the raw disk and writing
directly on the directories, it *cannot* work if you try to use it to
handle files with embedded NULs in their names.  Since the file names
passed as arguments to UNIX system calls are C strings, which *by
definition* cannot have embedded NULs, no UNIX system call can
possibly refer to such a file (unless you throw in a system call that
takes character arrays representing containing NON-NUL-terminated
strings as arguments).

kww@cbosgd.UUCP (03/02/87)

In article <563@aw.sei.cmu.edu.sei.cmu.edu> pdb@sei.cmu.edu (Patrick Barron) writes:
>
>As a last resort you could use 'clri' on the inode associated with that
>file (use 'ls -li' to find the inode numner).  fsck will certainly allow
>you to clear the directory entry once it realizes the inode's been zeroed.
>
>--Pat.


This was in response to renaming a directory that had an embbeded null
character in it, something like "D\0c" I believe.

What about using 'fsdb' (file system debugger) and run it on the raw
file system.  All you need to do is find the directory block of the
parent directory, and then find the "D\oc" entry and change it to "Doc".
With fsdb(1M) it is not too hard since it sorta understands UNIX file
systems.  If you don't have fsdb (e.g., like BSD systems maybe), adb(1)
will also do the trick when run on the raw device corresponding to the
file system, although with 'adb', you will have to compute disk offsets,
etc. yourself.

Oh yeah, to be on the safe side, run /etc/umount on the file system
BEFORE you start to ``play''.  (Especially if you have to use adb.)
Of course if its on root device, you can't do this, but then you ought
to do it in single user mode, after having sync(1M)'ed it a few times
to make sure everything has been flushed to the disk.  Its really not as
hard as you think it might be, especially if you have fsdb available.

Of course, all this discussion presumes that you have SU priviledges,
or writtable special files (E-gad!, talk about security holes!)

Good luck!

andys@men2a.UUCP (03/02/87)

Altos UNIX ports done in the last year or so tend to have been poorly
done, and as poorly tested.  Allegedly, they are cleaning up their
act somewhat.  Part of that effort has involved major cleanups of their
Unix ports for the 886, 2086, and 3068.  For the 2086, you want to get
your mitts on release 3.4, finally made aavilable the last week of February.

In theory, there should be no charge for the upgrade, as it could be 
construed as replacement of defective merchandise.

The grapevine has it that Altos is determined to make its software 
perform as well and as reliably as its hardware.  If they do, they will
easily have the most bang for the buck in the supermicro category.

--andys@men2a.UUCP

mjy@galbp.UUCP (Mike Yoffee) (03/05/87)

> the file because unlink can't find 'D\0c'.

....you could port 'fsdb' and get rid of it using
that utility - provided you have access to 'fsdb' or it's source.