Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @file myfind.c
- * Betriebssysteme MyFind File.
- * Beispiel 1
- *
- * @author
- * @author
- * @author
- *
- * @date 2012/03/01
- *
- * @version $Revision: 11 $
- *
- * @todo action-handling
- *
- * URL: $HeadURL$
- *
- * Last Modified: $Author: markus $
- */
- /*
- * -------------------------------------------------------------- includes --
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <time.h>
- #include <pwd.h>
- #include <grp.h>
- #include <unistd.h>
- #include <fnmatch.h>
- #include <stdlib.h>
- /*
- * --------------------------------------------------------------- defines --
- */
- #define PATHLEN 256
- enum BOOLEAN {FALSE, TRUE};
- enum Type
- {
- b, /**< block */
- c, /**< character */
- d, /**< directory */
- p, /**< named pipe (FIFO) */
- f, /**< regular file */
- l, /**< symbolic link; */
- s /**< socket */
- };
- /*
- * -------------------------------------------------------------- typedefs --
- */
- typedef struct Options {
- char * dirname;
- char * name;
- char * user;
- char * path;
- char * type;
- int ls;
- int nouser;
- int print;
- }Options;
- /*
- * --------------------------------------------------------------- globals --
- */
- /*
- * ------------------------------------------------------------- functions --
- */
- int do_dir(const char * dir_name, Options * params);
- void do_file(const char * file_name, Options * params, const struct stat * file_stats, const char * current_file);
- void usage();
- Options init_options();
- Options get_options (int num, char * params[]);
- void input_check(int num, char * params[], char * prog);
- int getpermissionstring(char * str, const int mode);
- void print_ls(const char * file_name, const struct stat * file_stats);
- /**
- *
- * \brief The most minimalistic C program
- *
- * This is the main entry point for any C program.
- *
- * \param argc the number of arguments
- * \param argv the arguments itselves (including the program name in argv[0])
- *
- * \return always "success"
- * \retval 0 always
- *
- */
- int main(int argc, char* argv[])
- {
- Options action;
- action = get_options(argc, argv);
- switch(do_dir(action.dirname,&action))
- {
- case 0: exit(EXIT_FAILURE);
- break;
- case 1: exit(EXIT_SUCCESS);
- break;
- }
- return 0;
- }
- /**
- *
- * \brief walk through directories/subdirectories
- *
- * walk through directories/subdirectories and calls for each entry
- * function do_file
- *
- * \param dir_name directory-name
- * \param parms used parameter
- *
- * \return unable to open or close directory
- * \return success
- * \retval EXIT_SUCCESS
- * \retval EXIT_FAILURE
- */
- int do_dir(const char * dir_name, Options * params){
- DIR *dir=NULL;
- struct dirent *dirent=NULL;
- char fpath[1024]="";
- struct stat st;
- /* open directory */
- if((dir=opendir(dir_name)) == NULL)
- {
- if (lstat(dir_name, &st) == -1)
- {
- perror("stat");
- return 0;
- }
- if (S_ISDIR(st.st_mode))
- {
- fprintf(stderr,"myfind: unable to open directory %s \n", dir_name);
- return 0;
- }
- else
- {
- do_file(dir_name,params,&st,dir_name);
- return 1;
- }
- }
- /* walk through the directory */
- while((dirent=readdir(dir)) != NULL)
- {
- /* ignore current and parent directory */
- if ( (strcmp(dirent->d_name, ".") == 0) || (strcmp(dirent->d_name, "..") == 0) )
- continue;
- /* necessary because readdir returns relative Path, to the entry before */
- memset(fpath, 0, sizeof(fpath));
- snprintf(fpath,sizeof(fpath),"%s/%s", dir_name, dirent->d_name);
- if (lstat(fpath, &st) == -1)
- {
- perror("stat");
- return 0;
- }
- do_file(fpath,params,&st, dirent->d_name);
- if (S_ISDIR(st.st_mode))
- do_dir(fpath,params);
- }
- /* close directory */
- if(closedir(dir) == -1)
- {
- fprintf(stderr,"myfind: unable to close directory %s\n", dir_name);
- return 0;
- }
- return 1;
- }
- /**
- *
- * \brief analyzes each directory-entry
- *
- * analyzes each directory-entry on the basis of the given parameters
- * if all parameters matches the entry is printed out
- *
- * \param file_name file/directory name
- * \param parms used parameter
- * \param file_stats file stats
- *
- * \return void
- */
- void do_file(const char * file_name, Options * params, const struct stat * file_stats, const char * current_file){
- int name_flag = TRUE;
- int user_flag = TRUE;
- int path_flag = TRUE;
- int type_flag = TRUE;
- int nouser_flag = TRUE;
- if(params->name != NULL){
- if(fnmatch(params->name, current_file, FNM_NOESCAPE| FNM_PERIOD))
- {
- name_flag = FALSE;
- }
- }
- if(params->path != NULL){
- if(fnmatch(params->path, file_name, FNM_PATHNAME))
- {
- path_flag = FALSE;
- }
- }
- if(params->user != NULL)
- {
- long int uid;
- /* is parameter user a uid or name */
- if((uid=strtol(params->user,NULL,0)))
- {
- if(uid!=file_stats->st_uid)
- user_flag = FALSE;
- }
- else
- {
- if(strcmp(params->user,getpwuid(file_stats->st_uid)->pw_name))
- user_flag = FALSE;
- }
- }
- if(params->type != NULL)
- {
- int searchtype = f;
- int filetype = f;
- switch (params->type[0])
- {
- case 'p': searchtype = p; break; /* named pipe (FIFO) */
- case 'c': searchtype = c; break; /* character special */
- case 'd': searchtype = d; break; /* directory */
- case 'b': searchtype = b; break; /* block special */
- case 'f': searchtype = f; break; /* regular file */
- case 'l': searchtype = l; break; /* symbolic link */
- case 's': searchtype = s; break; /* socket */
- default: fprintf(stderr,"myfind: invalid argument '%s' to `-type' \n", params->type);
- usage();
- break;
- }
- switch (file_stats->st_mode & 0xffffc00)
- {
- case 0x1000: filetype = p; break; /* named pipe (FIFO) */
- case 0x2000: filetype = c; break; /* character special */
- case 0x4000: filetype = d; break; /* directory */
- case 0x6000: filetype = b; break; /* block special */
- case 0x8000: filetype = f; break; /* regular file */
- case 0xa000: filetype = l; break; /* symbolic link */
- case 0xc000: filetype = s; break; /* socket */
- default: fprintf(stderr,"myfind: unknown type !!! %x", file_stats->st_mode & 0xffffc00);
- usage();
- break;
- }
- if(searchtype != filetype)
- type_flag = FALSE;
- }
- if(params->nouser == TRUE)
- {
- /* is user in /etc/passwd file */
- if (getpwuid(file_stats->st_uid))
- nouser_flag = FALSE;
- else
- nouser_flag = TRUE;
- }
- if (name_flag == TRUE && user_flag == TRUE && path_flag == TRUE && type_flag == TRUE && nouser_flag == TRUE)
- {
- if(params->ls == TRUE){
- print_ls(file_name,file_stats);
- }
- if(params->print == TRUE){
- printf("%s\n",file_name);
- }
- }
- }
- /**
- *
- * \brief print usage informations and exit programm
- *
- * \return void
- */
- void usage()
- {
- fprintf(stderr, "usage: myfind <directory> [ <action> ] ...\n");
- exit(1);
- }
- /**
- *
- * \brief initialisation of the option structure
- * \return Options
- */
- Options init_options(){
- Options init;
- init.dirname = NULL;
- init.name = NULL;
- init.path = NULL;
- init.type = NULL;
- init.user = NULL;
- init.nouser = FALSE;
- init.ls = FALSE;
- init.print = TRUE;
- return init;
- }
- /**
- *
- * \brief fill the option structur with the params of the command-line
- *
- * checks if all given params from the command-line are correct
- * an return the filled option structure
- * \param num number of the given params (from the command-line)
- * \param params array with all params (from the command-line)
- *
- * \return Options
- */
- Options get_options (int num, char * params[]){
- Options action = init_options();
- int i = 0;
- int count = 0;
- char * prog;
- if (num < 2)
- usage();
- prog=params[0];
- action.dirname = *(++params);
- if (num==2)
- action.print = TRUE;
- num--;
- input_check(num, params, prog);
- for(i=1;i<num;i++){
- if (0 == strcmp("-name", params[i])){
- i++;
- if(action.name == NULL)
- action.name = params[i];
- else
- count++;
- continue;
- }
- else if(0 == strcmp("-user", params[i])){
- i++;
- if(action.user == NULL)
- action.user = params[i];
- else
- count++;
- continue;
- }
- else if(0 == strcmp("-path", params[i])){
- i++;
- if(action.path == NULL)
- action.path = params[i];
- else
- count++;
- continue;
- }
- else if(0 == strcmp("-type", params[i])){
- i++;
- if(action.type == NULL)
- action.type = params[i];
- else
- count++;
- continue;
- }
- else if(0 == strcmp("-ls", params[i])){
- action.ls = TRUE;
- action.print = FALSE;
- if(count == 0)
- do_dir(action.dirname,&action);
- /* unset LS */
- action.ls = FALSE;
- count = 0;
- continue;
- }
- else if(0 == strcmp("-nouser", params[i])){
- action.nouser = TRUE;
- continue;
- }
- else if(0 == strcmp("-print", params[i])){
- action.print = TRUE;
- if(count == 0)
- do_dir(action.dirname,&action);
- /* unset Print */
- action.print = FALSE;
- count = 0;
- continue;
- }
- else {
- continue;
- }
- }
- return action;
- }
- /**
- *
- * \brief checks if myfind has the correct syntax
- *
- * checks if all given params from the command-line are correct
- * \param num number of the given params (from the command-line)
- * \param params array with all params (from the command-line)
- *
- */
- void input_check(int num, char * params[], char * prog){
- int i = 0;
- for(i=1;i<num;i++){
- if (0 == strcmp("-name", params[i])){
- i++;
- if (num == i){
- fprintf(stderr,"%s: missing argument to `-name'\n", prog);
- usage();
- }
- continue;
- }
- else if(0 == strcmp("-user", params[i])){
- i++;
- if (num == i){
- fprintf(stderr,"%s: missing argument to `-user'\n", prog);
- usage();
- }
- continue;
- }
- else if(0 == strcmp("-path", params[i])){
- i++;
- if (num == i){
- fprintf(stderr,"%s: missing argument to `-path'\n", prog);
- usage();
- }
- continue;
- }
- else if(0 == strcmp("-type", params[i])){
- i++;
- if (num == i){
- fprintf(stderr,"%s: missing argument to `-type'\n", prog);
- usage();
- }
- if (params[i][1] != '\0'){
- printf("myfind: invalid argument '%s' to `-type' \n",params[i]);
- usage();
- }
- switch (params[i][0])
- {
- case 'p': break; /* named pipe (FIFO) */
- case 'c': break; /* character special */
- case 'd': break; /* directory */
- case 'b': break; /* block special */
- case 'f': break; /* regular file */
- case 'l': break; /* symbolic link */
- case 's': break; /* socket */
- default: printf("myfind: invalid argument '%s' to `-type' \n", params[i]);
- usage();
- break;
- }
- continue;
- }
- else if(0 == strcmp("-ls", params[i])){
- continue;
- }
- else if(0 == strcmp("-nouser", params[i])){
- continue;
- }
- else if(0 == strcmp("-print", params[i])){
- continue;
- }
- else {
- fprintf(stderr,"%s: %s: unknown action\n", prog, params[i]);
- usage();
- }
- }
- }
- /* ----------------------------------------------------------------------- */
- /**
- \brief writes the permission-string
- \param str the string in which should be written
- \param mode the mode of the file (lstat-type)
- \return the type of the file (int)
- ----------------------------------------------------------------------- */
- int getpermissionstring(char * str, const int mode)
- {
- char type = '-'; int ret = f;
- switch (mode & 0xffffc00)
- {
- case 0x1000: type = 'p'; ret = p; break; /* named pipe (FIFO) */
- case 0x2000: type = 'c'; ret = c; break; /* character special */
- case 0x4000: type = 'd'; ret = d; break; /* directory */
- case 0x6000: type = 'b'; ret = b; break; /* block special */
- case 0x8000: type = '-'; ret = f; break; /* regular file */
- case 0xa000: type = 'l'; ret = l; break; /* symbolic link */
- case 0xc000: type = 's'; ret = s; break; /* socket */
- default: printf("myfind: getpermissionstring: unknown type %x", mode & 0xffffc00); break;
- }
- snprintf(str, 11, "%c%c%c%c%c%c%c%c%c%c",
- type,
- (mode & 0x0100) ? 'r' : '-',
- (mode & 0x0080) ? 'w' : '-',
- (mode & 0x0040) ? 'x' : '-',
- (mode & 0x0020) ? 'r' : '-',
- (mode & 0x0010) ? 'w' : '-',
- (mode & 0x0008) ? 'x' : '-',
- (mode & 0x0004) ? 'r' : '-',
- (mode & 0x0002) ? 'w' : '-',
- (mode & 0x0200) ? 't' : (mode & 0x0001) ? 'x' : '-' /* sticky b */
- );
- return (ret);
- }
- void print_ls(const char * file_name, const struct stat * file_stats)
- {
- char timestr[13]; char perm[11];
- struct tm brtm = *(localtime(&file_stats->st_mtime));
- int type = f;
- int linklen;
- char link_location[PATHLEN];
- char link[PATHLEN];
- strftime(timestr, 13, "%b %d %H:%M", &brtm);
- type = getpermissionstring(perm, file_stats->st_mode);
- if(type == l)
- {
- linklen = readlink(file_name, link_location, sizeof(link_location) - 1);
- if (linklen == -1){
- fprintf(stderr,"myfind: unable to read link of file: %s \n", file_name);
- link[0] = '\0';
- }
- else{
- link_location[linklen] = '\0';
- snprintf(link,sizeof(link),"-> %s",link_location);
- }
- }
- printf("%6ld %4ld %s %3d %-8s %-8s %8ld %s %s %s\n",
- file_stats->st_ino,
- file_stats->st_blocks,
- perm,
- (int) file_stats->st_nlink,
- getpwuid(file_stats->st_uid)->pw_name,
- getgrgid(file_stats->st_gid)->gr_name,
- file_stats->st_size,
- timestr,
- file_name,
- (type==l) ? link : " ");
- }
- /*
- * =================================================================== eof ==
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement