Help about programming ls-l in c segment violation

1

I'm crazy with this program that I'm doing in c and I can not get it to work well for me. What I'm doing is implementing in c two commands a ls-x and a ls-l when I try it with the directory "." , everything works for me and when I try it with any other directory, the ls-l I get segment violation, if you could guide me. I copy the code.

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include "util.h"

void lsx(DIR *dirp){
    printf("ls -x\n");
    struct dirent *direntp;
    while ((direntp = readdir(dirp)) != NULL) {
        if(strncmp(direntp->d_name, ".", 1)!=0||strncmp(direntp->d_name, "..", 1)!=0){
        printf("%s\t",direntp->d_name); 
        }
    }
    printf("\n");
    closedir(dirp);
}
void lsl(DIR *dirq){
    printf("ls -l\n");
    struct dirent *direntp;
    struct stat otra;
    struct passwd *pass;
    struct tm      *tm;
    struct group   *grp;
    while ((direntp = readdir(dirq)) != NULL) {
        if(strncmp(direntp->d_name, ".", 1)!=0||strncmp(direntp->d_name, "..", 1)!=0){
            stat(direntp->d_name, &otra);//Actualizamos el estado de los ficheros
            /* Realizamos los permisos del fichero con la estructura stat */
            printf( (S_ISDIR(otra.st_mode)) ? "d" : "-" );
            printf( (otra.st_mode & S_IRUSR) ? "r" : "-" );
            printf( (otra.st_mode & S_IWUSR) ? "w" : "-" );
            printf( (otra.st_mode & S_IXUSR) ? "x" : "-" );
            printf( (otra.st_mode & S_IRGRP) ? "r" : "-" );
            printf( (otra.st_mode & S_IWGRP) ? "w" : "-" );
            printf( (otra.st_mode & S_IXGRP) ? "x" : "-" );
            printf( (otra.st_mode & S_IROTH) ? "r" : "-" );
            printf( (otra.st_mode & S_IWOTH) ? "w" : "-" );
            printf( (otra.st_mode & S_IXOTH) ? "x" : "-" );
            printf("%-8.8s\t");
            /* Realizamos el nombre del propietario del fichero con la estructura passwd */
            pass=getpwuid(otra.st_uid);
            printf("%-8.8s\t",pass->pw_name);
            /* Realizamos el nombre del grupo del fichero con la estructura group */
            grp = getgrgid(otra.st_gid);
                printf("%-8.8s\t", grp->gr_name);
            /* Realizamos la ultima fecha de modificacion del fichero con la estructura tm */       
            printf("%s\t", ctime(&otra.st_mtime));
            printf("%s\n",direntp->d_name);
        }
    }
closedir(dirq);
}

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include "util.h"


int main (int argc, char *argv[]){
    if(argv[1]==NULL){//Si no pasamos por argumentos tomamos el directorio que en el que nos encontramos
        lsx(opendir("."));
        lsl(opendir("."));
    }else{
        lsx(opendir(argv[1]));
        lsl(opendir(argv[1]));
    }
}
    
asked by Pedrogg 09.11.2016 в 12:57
source

2 answers

0

Give segment violation only when you pass a non-existent directory as an argument; normal, because you do not check it at any time.

Modify

if(argv[1]==NULL){
 lsx(opendir("."));
 lsl(opendir("."));
} else {
 lsx(opendir(argv[1]));
 lsl(opendir(argv[1]));
}

to check the existence of the directory

if( argv[1] != NULL ) {
  DIR *path = opendir( argv[1] );
  if( ! path ) {
    printf( "El directorio no existe\n" );
  } else {
   lsx( path );
   lsl( path );
 }
}

Not checking the return of functions brings things like that. Get used to checking everything , until what is impossible to fail .

EDITO

As you have been told before (me and others), check the return of all the functions you use.

This code will fail as long as the file belongs to a non-existent (verified) user:

pass=getpwuid(otra.st_uid);
printf("%-8.8s\t",pass->pw_name);
grp = getgrgid(otra.st_gid);
printf("%-8.8s\t", grp->gr_name);

Change it to, for example:

pass=getpwuid(otra.st_uid)
printf("%-8.8s\t", pass ? pass->pw_name : "**" );

grp = getgrgid(otra.st_gid);
printf("%-8.8s\t", grp ? grp->gr_name : "**" );

and check the rest of the code, in case there is a function call from which you do not check the return.

    
answered by 09.11.2016 в 13:37
0

I already got it, the problem was here. You had to put another check as I was missing before.

if ((pass = getpwuid(otra.st_uid)) != NULL){
                printf(" %-8.8s", pass->pw_name);
            }else{
                    printf(" %-8d", otra.st_uid);
            }
            /* Realizamos el nombre del grupo del fichero con la estructura group */
            if ((grp = getgrgid(otra.st_gid)) != NULL){
                printf(" %-8.8s", grp->gr_name);
            }else{
                printf(" %-8d", otra.st_gid);
            }

Thank you very much for your help. I will have to focus more on the checks and possible departures.

    
answered by 09.11.2016 в 15:08