200 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								  (c) 2005 Peter Portmann (pp at bluewin.ch)
							 | 
						||
| 
								 | 
							
								  cinit.graph.text.c
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								  This script is written for the clinux-System and published
							 | 
						||
| 
								 | 
							
								  under the terms of GPL 2.0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Version: 0.2
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  ChangeLog:
							 | 
						||
| 
								 | 
							
								    Version 0.2 (Peter Portmann):
							 | 
						||
| 
								 | 
							
								      * Not assigned link destinies are marked by (!).
							 | 
						||
| 
								 | 
							
								      * Not readable directories are marked by "directory not readable".
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    Version 0.1 (Peter Portmann):
							 | 
						||
| 
								 | 
							
								      * Print of the directory structure of the contained files and links
							 | 
						||
| 
								 | 
							
								        without following the links.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Todo:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Features:
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								//#include <sys/types.h>
							 | 
						||
| 
								 | 
							
								#include <sys/stat.h>
							 | 
						||
| 
								 | 
							
								#include <dirent.h>
							 | 
						||
| 
								 | 
							
								#include <limits.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								#include <unistd.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include "cinit.h"
							 | 
						||
| 
								 | 
							
								#include "error.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FTW_F 1   /* file isn't a directory */
							 | 
						||
| 
								 | 
							
								#define FTW_D 2   /* file is a directory */
							 | 
						||
| 
								 | 
							
								#define FTW_DNR 3 /* not readable directory */
							 | 
						||
| 
								 | 
							
								#define FTW_NS 4  /* unsuccesfully stat on this file */
							 | 
						||
| 
								 | 
							
								#define MAX_CHAR   4096
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * cinit.gaph.text - textual representation of the cinit directory
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define CSERVICE_BANNER    "cinit.gaph.text - textual representatio of the cinitdirectory\n\n"
							 | 
						||
| 
								 | 
							
								#define USAGE_TEXT         "\n\nUsage:\n\ncinit.gaph.text <path>\n"  \
							 | 
						||
| 
								 | 
							
								   "\tpath\t- cinit installationpath\n"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef int EACH_ENTRY(const char *, const struct stat *, int);
							 | 
						||
| 
								 | 
							
								typedef enum  { FALSE=0, TRUE=1 }  bool;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static char dirpath[PATH_MAX];
							 | 
						||
| 
								 | 
							
								static int depth = 0;
							 | 
						||
| 
								 | 
							
								static long int filecount = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static EACH_ENTRY each_entry;
							 | 
						||
| 
								 | 
							
								static int pp_ftw(char *, EACH_ENTRY *);
							 | 
						||
| 
								 | 
							
								static int each_getinfo(EACH_ENTRY *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * pp_ftw: file tree walk
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static int pp_ftw(char *filepath, EACH_ENTRY *function)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   int n;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(chdir(filepath) < 0) /* In angegebenen Pfad wechseln */
							 | 
						||
| 
								 | 
							
								      err_msg(FATAL_SYS, "can't change to %s", filepath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(getcwd(dirpath, PATH_MAX) == 0) /* Absoluten Pfadnamen ermitteln */
							 | 
						||
| 
								 | 
							
								      err_msg(FATAL_SYS, "error using getcwd for %s", filepath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   n = each_getinfo(function);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   return(n);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * each_getinfo: get more info for each file.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static int each_getinfo(EACH_ENTRY *function)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   struct stat statpuff;
							 | 
						||
| 
								 | 
							
								   struct dirent *direntz;
							 | 
						||
| 
								 | 
							
								   DIR *dirz;
							 | 
						||
| 
								 | 
							
								   int n;
							 | 
						||
| 
								 | 
							
								   char *zgr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(lstat(dirpath, &statpuff) < 0)
							 | 
						||
| 
								 | 
							
								      return(function(dirpath, &statpuff, FTW_NS)); /* Error on stat */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(S_ISDIR(statpuff.st_mode) == 0)
							 | 
						||
| 
								 | 
							
								      return(function(dirpath, &statpuff, FTW_F)); /* no directory */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   /* It's a directory.
							 | 
						||
| 
								 | 
							
								    * Call function() for it. After that handel each file in the directory. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if((dirz = opendir(dirpath)) == NULL) { /* Directory not readable */
							 | 
						||
| 
								 | 
							
								      closedir(dirz);
							 | 
						||
| 
								 | 
							
								      return(function(dirpath, &statpuff, FTW_DNR));
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if((n = function(dirpath, &statpuff, FTW_D)) != 0) /* return the directorydirpath */
							 | 
						||
| 
								 | 
							
								      return(n);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   zgr = dirpath + strlen(dirpath); /* append slash to the dirpathname */
							 | 
						||
| 
								 | 
							
								   *zgr++ = '/';
							 | 
						||
| 
								 | 
							
								   *zgr = '\0';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   while((direntz = readdir(dirz)) != NULL) {
							 | 
						||
| 
								 | 
							
								      /* ignor . and .. */
							 | 
						||
| 
								 | 
							
								      if(strcmp(direntz->d_name, ".") && strcmp(direntz->d_name, "..")) {
							 | 
						||
| 
								 | 
							
								         strcpy(zgr, direntz->d_name); /* append filename after slash */
							 | 
						||
| 
								 | 
							
								         depth++;
							 | 
						||
| 
								 | 
							
								         if(each_getinfo(function) != 0) { /* Recursion */
							 | 
						||
| 
								 | 
							
								            depth--;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         depth--;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								   *(zgr-1) = '\0'; /* deleting evrything after the slash */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   if(closedir(dirz) < 0)
							 | 
						||
| 
								 | 
							
								      err_msg(WARNING, "closedir for %s failed", dirpath);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   return(n);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * each_entry: handling each file and build the graph step by step.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static int each_entry(const char *filepath, const struct stat *statzgr, int filetype)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   struct stat statpuff;
							 | 
						||
| 
								 | 
							
								   static bool erstemal=TRUE;
							 | 
						||
| 
								 | 
							
								   int i;
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								   char link[MAX_CHAR];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   filecount++;
							 | 
						||
| 
								 | 
							
								   if(!erstemal) {
							 | 
						||
| 
								 | 
							
								      for(i=1 ; i<=depth ; i++)
							 | 
						||
| 
								 | 
							
								         printf("%4c|", ' ');
							 | 
						||
| 
								 | 
							
								      printf("----%s", strrchr(filepath, '/')+1);
							 | 
						||
| 
								 | 
							
								   } else {
							 | 
						||
| 
								 | 
							
								      printf("%s", filepath);
							 | 
						||
| 
								 | 
							
								      erstemal = FALSE;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   switch(filetype) {
							 | 
						||
| 
								 | 
							
								      case FTW_F:
							 | 
						||
| 
								 | 
							
								         switch(statzgr->st_mode & S_IFMT) {
							 | 
						||
| 
								 | 
							
								            case S_IFREG: break;
							 | 
						||
| 
								 | 
							
								            case S_IFCHR: printf(" c"); break;
							 | 
						||
| 
								 | 
							
								            case S_IFBLK: printf(" b"); break;
							 | 
						||
| 
								 | 
							
								            case S_IFIFO: printf(" f"); break;
							 | 
						||
| 
								 | 
							
								            case S_IFLNK: 
							 | 
						||
| 
								 | 
							
								               printf(" -> "); 
							 | 
						||
| 
								 | 
							
								               if(( i=readlink(filepath, link, MAX_CHAR)) != -1)
							 | 
						||
| 
								 | 
							
								                  printf("%.*s", i, link);
							 | 
						||
| 
								 | 
							
								                  if(stat(filepath, &statpuff) < 0)
							 | 
						||
| 
								 | 
							
								                     printf(" (!)");
							 | 
						||
| 
								 | 
							
								               break;
							 | 
						||
| 
								 | 
							
								            case S_IFSOCK: printf(" s"); break;
							 | 
						||
| 
								 | 
							
								            default: printf(" ?"); break;
							 | 
						||
| 
								 | 
							
								         }
							 | 
						||
| 
								 | 
							
								         printf("\n");
							 | 
						||
| 
								 | 
							
								         break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      case FTW_D:
							 | 
						||
| 
								 | 
							
								         printf("/\n");
							 | 
						||
| 
								 | 
							
								         break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      case FTW_DNR:
							 | 
						||
| 
								 | 
							
								         printf("/ directory not readable\n");
							 | 
						||
| 
								 | 
							
								         break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      case FTW_NS:
							 | 
						||
| 
								 | 
							
								         err_msg(WARNING_SYS, "Error using 'stat' on file %s", filepath);
							 | 
						||
| 
								 | 
							
								         break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      default:
							 | 
						||
| 
								 | 
							
								         err_msg(FATAL_SYS, "Unknown Filetype (%d) by file %s", filetype, filepath);
							 | 
						||
| 
								 | 
							
								         break;
							 | 
						||
| 
								 | 
							
								   }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   return(0);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/***********************************************************************
							 | 
						||
| 
								 | 
							
								 * main:
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								int main(int argc, char *argv[])
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								   if(argc != 2)
							 | 
						||
| 
								 | 
							
								      usage(CSERVICE_BANNER, USAGE_TEXT);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   exit(pp_ftw(argv[1], each_entry));
							 | 
						||
| 
								 | 
							
								}
							 |