How do you find the symbolic links to files.
Barry Shein
bzs at world.std.com
Tue Dec 11 11:06:15 AEST 1990
Actually, under BSD, you can write a fairly portable program to
identify holes without getting intimate with the disk, tho I'm not
entirely certain if there are any, um, holes in it, probably.
This approace *is* "destructive" of the file (it destroys the holes)
tho when you're done you can reconstruct the file with the holes put
back.
Obviously this won't work if you don't have room for the exapnded file
(tho some shenanigans might only require you to have the size of the
unexpanded file plus one block available, I dunno, would take some
thought.)
The basic idea goes like this:
1. Holes always read back as a block of zeros, so only
blocks that appear to be filled with zeros are interesting.
2. If you rewrite a real hole with all zeros (still
with me?) the number of blocks in the file will change,
a stat() will indicate this.
Here's a basic program (which could be improved in various ways, but
illustrates the idea) which prints out which blocks in the file are
holes, have fun picking holes in it (at least grant me that I said it
was BSD-only)!
--------------------
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
main(argc,argv) int argc; char **argv;
{
int i;
int fd;
char *buf;
struct stat st, nst;
if((fd = open("TMPTMP",O_RDWR)) < 0) {
perror("open");
exit(1);
}
if(fstat(fd,&st) < 0) {
perror("stat");
exit(1);
}
buf = (char *)malloc(st.st_blksize);
for(i=0;;i++) {
if(read(fd,buf,st.st_blksize) != st.st_blksize)
exit(0);
if(allzeros(buf,st.st_blksize)) {
lseek(fd,-st.st_blksize,L_INCR);
write(fd,buf,st.st_blksize);
fstat(fd,&nst);
if(nst.st_blocks > st.st_blocks)
printf("block %d is a hole\n",i);
st = nst;
}
}
}
allzeros(p,n) register char *p; register int n;
{
while(n--)
if(*p++ != '\0')
return(0);
return(1);
}
--------------------
--
-Barry Shein
Software Tool & Die | {xylogics,uunet}!world!bzs | bzs at world.std.com
Purveyors to the Trade | Voice: 617-739-0202 | Login: 617-739-WRLD
More information about the Comp.unix.internals
mailing list