ls2.c------------------------------------------- /* ls2.c * purpose list content
ID: 3878866 • Letter: L
Question
ls2.c-------------------------------------------
/* ls2.c
* purpose list contents of directory or directories
* action if no args, use . else list files in args
* note uses stat and pwd.h and grp.h
* BUG: try ls2 /tmp
*/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
void do_ls(char[]);
void dostat(char *);
void show_file_info( char *, struct stat *);
void mode_to_letters( int , char [] );
char *uid_to_name( uid_t );
char *gid_to_name( gid_t );
main(int ac, char *av[])
{
if ( ac == 1 )
do_ls( "." );
else
while ( --ac ){
printf("%s: ", *++av );
do_ls( *av );
}
}
void do_ls( char dirname[] )
/*
* list files in directory called dirname
*/
{
DIR *dir_ptr; /* the directory */
struct dirent *direntp; /* each entry */
if ( ( dir_ptr = opendir( dirname ) ) == NULL )
fprintf(stderr,"ls1: cannot open %s ", dirname);
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
dostat( direntp->d_name );
closedir(dir_ptr);
}
}
void dostat( char *filename )
{
struct stat info;
if ( stat(filename, &info) == -1 ) /* cannot stat */
perror( filename ); /* say why */
else /* else show info */
show_file_info( filename, &info );
}
void show_file_info( char *filename, struct stat *info_p )
/*
* display the info about 'filename'. The info is stored in struct at *info_p
*/
{
char *uid_to_name(), *ctime(), *gid_to_name(), *filemode();
void mode_to_letters();
char modestr[11];
mode_to_letters( info_p->st_mode, modestr );
printf( "%s" , modestr );
printf( "%4d " , (int) info_p->st_nlink);
printf( "%-8s " , uid_to_name(info_p->st_uid) );
printf( "%-8s " , gid_to_name(info_p->st_gid) );
printf( "%8ld " , (long)info_p->st_size);
printf( "%.12s ", 4+ctime(&info_p->st_mtime));
printf( "%s " , filename );
}
/*
* utility functions
*/
/*
* This function takes a mode value and a char array
* and puts into the char array the file type and the
* nine letters that correspond to the bits in mode.
* NOTE: It does not code setuid, setgid, and sticky
* codes
*/
void mode_to_letters( int mode, char str[] )
{
strcpy( str, "----------" ); /* default=no perms */
if ( S_ISDIR(mode) ) str[0] = 'd'; /* directory? */
if ( S_ISCHR(mode) ) str[0] = 'c'; /* char devices */
if ( S_ISBLK(mode) ) str[0] = 'b'; /* block device */
if ( mode & S_IRUSR ) str[1] = 'r'; /* 3 bits for user */
if ( mode & S_IWUSR ) str[2] = 'w';
if ( mode & S_IXUSR ) str[3] = 'x';
if ( mode & S_IRGRP ) str[4] = 'r'; /* 3 bits for group */
if ( mode & S_IWGRP ) str[5] = 'w';
if ( mode & S_IXGRP ) str[6] = 'x';
if ( mode & S_IROTH ) str[7] = 'r'; /* 3 bits for other */
if ( mode & S_IWOTH ) str[8] = 'w';
if ( mode & S_IXOTH ) str[9] = 'x';
}
#include <pwd.h>
char *uid_to_name( uid_t uid )
/*
* returns pointer to username associated with uid, uses getpw()
*/
{
struct passwd *getpwuid(), *pw_ptr;
static char numstr[10];
if ( ( pw_ptr = getpwuid( uid ) ) == NULL ){
sprintf(numstr,"%d", uid);
return numstr;
}
else
return pw_ptr->pw_name ;
}
#include <grp.h>
char *gid_to_name( gid_t gid )
/*
* returns pointer to group number gid. used getgrgid(3)
*/
{
struct group *getgrgid(), *grp_ptr;
static char numstr[10];
if ( ( grp_ptr = getgrgid(gid) ) == NULL ){
sprintf(numstr,"%d", gid);
return numstr;
}
else
return grp_ptr->gr_name;
}
Your task is to extend 1s2.c into ls3.c such that with --detail flag the program also outputs the current working directory (use getcwd function) o the total number directories in the current directory o the total number of files that are writeable by the current user he program should print out those numbers before exit. Hint You can modify do_ls0 and dostat0. For this lab, you can either use a global variable (bad practice btw), or return an int instead of void in dostat0 (a little better but is still a bad practice) or pass an int* to dostat0 fyou use global variables, remember to initialize it to 0 To know if a file is writeable by the current user (you) check the following; IF (current user is the owner of the file AND w bit is set in usr field) OR IF (current user is a member of the same group as the file AND w bit is set in grp field) OR IF (w bit is set in others field, so everyone can modify the file) Example result Current working directory: /export/home1/hessamla/codes/ number of directories: Total number of owner riteable files: 4 The new file name is ls3.c. The program must be modular, i.e. use separated functions to carry out the required functionalities. Furthermore, each function must be written in a separate c file. Header files must be used and included in the header file to define the functions. Finally, write a makefile to compile the whole project.Explanation / Answer
# include <stdio.h>
# include <sys/types.h>
# include <dirent.h>
# include <sys/stat.h>
# include <pwd.h>
# include <grp.h>
void do_ls( char[] );
void dostat( char * );
void show_file_info( char *, struct stat * );
void mode_to_letters( int, char [] );
char * uid_to_name( uid_t );
char * gid_to_name( gid_t );
main( int ac, char * av[] )
{
if( ac == 1 )
do_ls(".");
else
while( --ac )
{
printf("%s: ", *++av);
do_ls( *av );
}
}
void do_ls( char dirname[] )
{
DIR * dir_ptr;
struct dirent * direntp;
if( ( dir_ptr = opendir( dirname ) ) == NULL )
fprintf( stderr,"ls1: cannot open %s ", dirname);
else
{
while( (direntp = readdir( dir_ptr ) ) != NULL )
dostat( direntp->d_name );
closedir( dir_ptr);
}
}
void dostat( char * filename )
{
struct stat info;
if( stat( filename, &info ) == -1 )
perror( filename );
else
show_file_info( filename, &info );
}
void show_file_info( char * filename, struct stat * info_p )
{
char * uid_to_name(), * ctime(), *gid_to_name(), * filemode();
void mode_to_letter();
char modestr[11];
mode_to_letters( info_p->st_mode, modestr );
printf(" %s ", modestr );
printf(" %4d", ( int )info_p->st_nlink );
printf(" % -8s ", uid_to_name( info_p->st_nlink ));
printf(" % -8s ", gid_to_name( info_p->st_gid ) );
printf(" %8ld", (long)info_p->st_size );
printf(" %.12s", 4+ctime( &info_p->st_mtime ));
printf(" %s ", filename);
}
void mode_to_letters ( int mode, char str[] )
{
strcpy( str, "---------" );
if( S_ISDIR( mode ))
str[0] = 'd';
if( S_ISCHR( mode ))
str[0] = 'c';
if( S_ISBLK( mode ))
str[0] = 'd';
if( mode & S_IRUSR )
str[1] = 'r';
if( mode & S_IWUSR )
str[2] = 'w';
if( mode & S_IXUSR )
str[3] = 'x';
if( mode & S_IRGRP )
str[4] = 'r';
if( mode & S_IWGRP )
str[5] = 'w';
if( mode & S_IXGRP )
str[6] = 'x';
if( mode & S_IROTH )
str[7] = 'r';
if( mode & S_IWOTH )
str[8] = 'w';
if( mode & S_IXOTH )
str[9] = 'x';
}
char * gid_to_name( gid_t gid )
{
struct group * getgrgid(), * grp_ptr;
static char numstr[10];
if(( grp_ptr = getgrgid( gid )) == NULL )
{
sprintf(numstr, "%d", gid );
return numstr;
}
else
return grp_ptr->gr_name;
}
char * uid_to_name( uid_t uid )
{
struct passwd * getpwuid(), * pw_ptr;
static char numstr[10];
if( ( pw_ptr = getpwuid( uid)) == NULL )
{
sprintf(numstr, "%d", uid );
return numstr;
}
else
return pw_ptr->pw_name;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.