Bizarre Modem Problems
chris at umcp-cs.UUCP
chris at umcp-cs.UUCP
Sun Jul 20 21:33:20 AEST 1986
I cannot help with your `bizarre' (sic: it may help to think of
a `bizarre bazzar') modem problem, but this one is not hard:
In article <1530 at cwruecmp.UUCP> rynes at cwruecmp.UUCP (Edward M. Rynes
Esq.) writes:
>The following program fragment is supposed to remake directories
>that have many unused entries in them. (uucp/news spool directories)
>The first pass apears to run fine. But in the second pass all of the
>`stat's fail (bad address). Something in the first pass appears to
>be screwing up the directory. Am I missing something?
> <path is the original directory>
> <ptmp is a newly created temp directory>
> <dp = opendir(path)>
>
> /* First pass -- copy all non-empty files */
>
> for(dent=readdir(dp); dent; dent=readdir(dp)){
why not `while ((dent = readdir(dp)) != NULL)'?
[no occurrences of `stat'; much deleted]
> closedir(dp);
>
> unlink(path);
Ai! You do NOT want to `unlink' a directory. Use `rmdir'!
> if(rename(ptmp, path)){
> fprintf(stderr,"Can't rename directory!\n");
> exit(-1);
> }
>
> /* Second pass -- trim sub directories */
>
> if((dp=opendir(path)) == NULL){
> fprintf(stderr, "Can't access `%s'!\n", path);
> exit(3);
> }
>
> for(dent=readdir(dp); dent; dent=readdir(dp)){
Again, one `while' would certainly be simpler. Ah well.
> if(!strcmp(dent->d_name, ".") || ! strcmp(dent->d_name, ".."))
> continue;
`!strcmp()' is, in my opinion, bad style: it implies strcmp() is a
boolean function, when in fact it is a ternary function. Again:
ah well.
> sprintf(pent, "%s/%s", path, dent->d_name);
>
> if(stat(pent, buf))
> perror("trimdirs");
This *call* is fine: it passes a `char *' and a `struct stat *'.
But to what `struct stat' does `buf' point? Given the error you
got, it clearly points to no `struct stat' at all. It is probably
either `(struct stat *)NULL' or rubbish. You need to create one
somewhere (global, on the stack, or even on the heap if you wish)
and make `buf' point to it.
> if(buf && buf->st_mode & S_IFDIR)
The test on `buf' is redundant; this is equivalent to
/* excessively parenthesised, for demonstration purposes only: */
if ((buf != NULL) && ((buf->st_mode & S_IFDIR) != 0))
If buf is equal to NULL (0), the stat will have failed, and you
will not reach this statement.
> trimdir(path, dent->d_name);
> }
>
> closedir(dp);
There are some non-trivial problems for a good general purpose
directory squeezer. It is difficult (to say the least) to squeeze
the top level directory of a mounted file system. Care must be
taken during a recursive squeeze not to cross mount points. More
care should be taken to avoid running out of file descriptors in
mid-squeeze; and the program should be prepared to recover from an
error during squeezing a directory (it should put all the names
back, if possible).
On the other hand, you can simply write something that returns
a success/failure exit code, and let the operator deal with any
catastrophes. . . .
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP: seismo!umcp-cs!chris
CSNet: chris at umcp-cs ARPA: chris at mimsy.umd.edu
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list