home *** CD-ROM | disk | FTP | other *** search
- From: jason@violet.berkeley.edu (Jason Venner)
- Newsgroups: comp.sources.misc
- Subject: v02i072: checklink - check for symlinks in limbo
- Message-ID: <7489@ncoast.UUCP>
- Date: 9 Mar 88 23:22:50 GMT
- Approved: allbery@ncoast.UUCP
-
- Comp.sources.misc: Volume 2, Issue 72
- Submitted-By: "Jason Venner" <jason@violet.berkeley.edu>
- Archive-Name: checklink
-
- This is the first pass of a program that walks through the directories
- listed on the command link, and prints out the names of the
- unresolvable symbolic links, and what they point to on stdout.
- Error messages are reported on stderr.
- the exit code is the sum of the unresolved symbolic links + sum of non
- fatal errors.
- It has only tested on BSD systems. [So how many non-BSD systems have symbolic
- links? ++bsa]
-
- #--------------------------------CUT HERE-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # -rw-rw-rw- 1 allbery uucp 3108 Mar 9 18:17 checklink.c
- #
- echo 'x - checklink.c'
- if test -f checklink.c; then echo 'shar: not overwriting checklink.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > checklink.c
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X
- Xchar *name;
- X
- Xmain( argc, argv )
- Xint argc;
- Xchar **argv;
- X{
- X
- X char *dir;
- X char *path;
- X char cwd[MAXNAMLEN+1];
- X char* getcwd();
- X char* rindex();
- X int err_count;
- X
- X name = argv[0];
- X cwd[MAXNAMLEN] = '\0';
- X if( !getwd( cwd ) ) {
- X fprintf( stderr, "%s:unable to get current working directory, %s", name, cwd );
- X exit( 1 );
- X }
- X for( argc--, argv++, err_count = 0; argc; argc--, argv++ ) {
- X if( chdir( argv[0] ) == -1 ) {
- X fprintf( stderr, "%s:unable to chdir to %s\n", name, dir );
- X perror( "" );
- X err_count++;
- X }
- X if( (dir = rindex( argv[0], '/' )) ) {
- X *dir++ = '\0';
- X path = argv[0];
- X } else {
- X dir = argv[0];
- X path = ".";
- X }
- X err_count += check_link( dir, path );
- X if( chdir( cwd ) == -1 ) {
- X fprintf( stderr, "%s:unable to chdir to %s\n", name, cwd );
- X perror( "" );
- X exit( 2 );
- X }
- X }
- X exit( err_count );
- X}
- X
- Xcheck_link( top, path )
- Xchar *top;
- Xchar *path;
- X{
- X
- X DIR *dptr;
- X DIR* opendir();
- X char cwd[MAXNAMLEN+1];
- X char link_name[MAXNAMLEN+1];
- X char* sprintf();
- X extern char *name;
- X int err_count;
- X int link_size;
- X off_t offset;
- X off_t telldir();
- X struct direct *dent;
- X struct direct* readdir();
- X struct stat stat;
- X
- X (void) sprintf( cwd, "%s/%s", path, top );
- X if( !(dptr = opendir( "." )) ) {
- X fprintf( stderr, "%s:unable to open directory %s", name, cwd );
- X perror( "" );
- X return 1;
- X }
- X if( !readdir( dptr ) || !readdir( dptr ) ) {
- X fprintf( stderr, "%s:unable to read '.' or '..' in %s\n",
- X name, cwd );
- X perror( "" );
- X (void) closedir( dptr );
- X return 1;
- X }
- X err_count = 0;
- X link_name[MAXNAMLEN] = '\0';
- X while( (dent = readdir( dptr )) ) {
- X if( lstat( dent->d_name, &stat ) == -1 ) {
- X fprintf( stderr, "%s:unable to lstat %s/%s", name, cwd, dent->d_name );
- X perror( "" );
- X err_count++;
- X continue;
- X }
- X switch( stat.st_mode & S_IFMT ) {
- X case S_IFDIR:
- X if( (offset = telldir( dptr )) == -1 ) {
- X fprintf( stderr, "%s:unable to telldir on %s\n", cwd );
- X perror( "" );
- X err_count++;
- X continue;
- X }
- X (void) closedir( dptr );
- X if( chdir( dent->d_name ) == -1 ) {
- X fprintf( stderr, "%s:unable to chdir to %s/%s", name, cwd, dent->d_name );
- X perror( "" );
- X return ++err_count;
- X }
- X err_count += check_link( dent->d_name, cwd );
- X if( chdir( ".." ) == -1 && chdir( cwd ) == -1 ) {
- X fprintf( stderr, "%s:unable to chdir up to %s", name, cwd);
- X return ++err_count;
- X }
- X if( !(dptr = opendir( "." )) ) {
- X fprintf( stderr, "%s:unable to reopendir %s", name, cwd );
- X perror( "" );
- X return ++err_count;
- X }
- X seekdir( dptr, offset, 0 );
- X break;
- X case S_IFLNK:
- X if( (link_size = readlink( dent->d_name, link_name, MAXNAMLEN )) == -1 ) {
- X fprintf( stderr, "%s:unable to readlink on %s/%s", cwd, dent->d_name );
- X perror( "" );
- X err_count++;
- X continue;
- X }
- X link_name[link_size] = '\0';
- X if( access( link_name, F_OK ) == -1 ) {
- X printf( "%s/%s %s\n", cwd, dent->d_name, link_name );
- X err_count++;
- X }
- X break;
- X default:
- X break;
- X }
- X }
- X (void) closedir( dptr );
- X return err_count;
- X}
- ________This_Is_The_END________
- if test `wc -c < checklink.c` -ne 3108; then
- echo 'shar: checklink.c was damaged during transit (should have been 3108 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-