0

So I'm working on a C program with UNIX as its terminal, and the program is supposed to call my directory recursively. The output should give me the directory themselves and the time period they were modified.

The code works, it compiles well, but it refuses to display its output. And right now all I need is to display the output. But this is what it gives me... I've tried ./compdir, ./compdir dir1 dir2, and also ./compdir dir2 dir1...the only possible solution in the UNIX terminal, but to no avail.

the output it gives me

Can someone help me out? Here is the code down below. I appreciate your help.

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

#define E_INVALIDSWITCH  100
#define E_TOOMANYPARAMS  101
#define E_TOOFEWPARAMS   102
#define E_OPENDIRFAIL    103

void status();        
void greetDirectory(char * baseDir, char * modDir);

int main(int argc, char ** argv)
{
    int R_switch = 0;
    char * modDir = NULL;
    char * baseDir = NULL;

    int i;
    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {

            if (strcmp(argv[i], "-R") == 0)
            {
            R_switch = 1;
            }

            else
            {
                fprintf(stderr, "Error: Invalid switch %s\n", argv[i]);
                status();
                return E_INVALIDSWITCH;
            }
        }

        else
        {
            if (baseDir == NULL)
            {
                baseDir = argv[i];
            }

            else if (modDir == NULL)
            {
                modDir = argv[i];
            }

            else
            {
                fprintf(stderr, "Error: Too many parameters\n");
                status();
                return E_TOOMANYPARAMS;
            }
        }
    }

    if (modDir == NULL)
    {
        fprintf(stderr, "Error: Too few parameters\n");
        status();
        return E_TOOFEWPARAMS;
    }

    if (R_switch)
    {
    greetDirectory(baseDir, modDir);
    }
    return 0;
}

void status()
{
    printf("\t-R\tGreet all files in current directory\n");
    printf("\t<modDir>\tName of person being greeted\n");
}

char *formatdate(char *buff, time_t val)
{
    strftime(buff,200, "%d.%m.%Y %H:%M:%S", localtime(&val));
    return buff;
}

void greetDirectory(char * baseDir, char * modDir)
{
    DIR * directory;
    struct dirent * dirInfo;

    directory = opendir(baseDir);
    if (directory == NULL)
    {
        fprintf(stderr,
            "opendir() failed for '%s', errno=%d\n",
            baseDir,
            errno);
        exit(E_OPENDIRFAIL);
    }

    while((dirInfo = readdir(directory)) != NULL)
    {
        if (strcmp(dirInfo->d_name, ".") != 0 &&
            strcmp(dirInfo->d_name, "..") != 0)
        {
            /* BASE DIR*/
            char basePathName[PATH_MAX];
            strcpy(basePathName, baseDir);
            strcat(basePathName, "/");
            strcat(basePathName, dirInfo->d_name);

            /* MOD DIR */
            char modPathName[PATH_MAX];
            strcpy(modPathName, modDir);
            strcat(modPathName, "/");
            strcat(modPathName, dirInfo->d_name);

            struct stat statBuf;
            struct stat otherStatBuf;
            if (stat(basePathName, &statBuf) == -1)
            {
                /* error! */
                fprintf(stderr, "stat() failed for '%s'", basePathName);
            }
            else
            {
                //display time
                stat(modPathName, &otherStatBuf);
                if (statBuf.st_mtime > otherStatBuf.st_mtime)
                {
                    char date[36];
                    printf("Modify: %s\n", formatdate(date, otherStatBuf.st_mtime));
                }

                if (S_ISDIR(statBuf.st_mode))
                {
                    /* if this is a directory, then recurse! */
                    greetDirectory(basePathName, modPathName);
                }
                else
                {
                    /* else if it's a file, then greet it! */
                    printf("entry name = %s\n", modPathName);
                }
            }
        }
    }

    closedir(directory);    
}
4
  • 4
    Have you tried stepping through the code with a debugger to isolate your issue? Commented Aug 6, 2016 at 23:12
  • I honestly don't know how to debug it. :( Commented Aug 6, 2016 at 23:16
  • 4
    Check out using gdb in your free time. There are plenty of tutorials on the web on using it. Commented Aug 6, 2016 at 23:19
  • 1
    Your diagnosis of "C code not displaying output" can't be correct, as we can see that your printf("..) functions and fprintf(stderr,...) are displaying output. Those are the only 2 functions you are using that should produce output. So, as mentioned above, this must be a logic problem, that you're not getting to the code branch where you expect. If getting upto speed with debugger is too much, add closing else blocks that display msg like fprintf(stderr,"Unexpected arrived at else#2, vars i=%d \t modPathname=%s\n" , i, modPathname) to see what the unexpected values are. Good luck Commented Aug 6, 2016 at 23:27

2 Answers 2

2

Your code will give output only when you specify the -R switch.

If you do not want this behavior, you need to remove if block on line 72 and call greetDirectory function directly.

// Remove if block 

if (R_switch)
{
    greetDirectory(baseDir, modDir);
}

// Replace with 

greetDirectory(baseDir, modDir);
Sign up to request clarification or add additional context in comments.

Comments

1

Here is the full code:

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

#define E_INVALIDSWITCH  100
#define E_TOOMANYPARAMS  101
#define E_TOOFEWPARAMS   102
#define E_OPENDIRFAIL    103

#define MAX_DIR_NAME_SIZE 100

void status();        
void greetDirectory(char * baseDir, char * modDir);

int main(int argc, char ** argv)
{
    int R_switch = 0;
    char modDir[MAX_DIR_NAME_SIZE] = {0};
    char baseDir[MAX_DIR_NAME_SIZE] = {0};

    int i;
    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] == '-')
        {

            if (strcmp(argv[i], "-R") == 0)
            {
            R_switch = 1;
            continue;
            }

            else
            {
                fprintf(stderr, "Error: Invalid switch %s\n", argv[i]);
                status();
                return E_INVALIDSWITCH;
            }
        }

        else
        {
            if (baseDir[0] == 0 && modDir[0] == 0)
            {
                strcpy(baseDir, argv[i]);
                strcpy(modDir, argv[i]);
            }
            else
            {
                fprintf(stderr, "Error: Too many parameters\n");
                status();
                return E_TOOMANYPARAMS;
            }
        }
    }

    if (modDir[0] == 0)
    {
        fprintf(stderr, "Error: Too few parameters\n");
        status();
        return E_TOOFEWPARAMS;
    }

    if (R_switch)
    {
    greetDirectory(baseDir, modDir);
    }
    return 0;
}

void status()
{
    printf("\t-R\tGreet all files in current directory\n");
    printf("\t<modDir>\tName of person being greeted\n");
}

char *formatdate(char *buff, time_t val)
{
    strftime(buff,200, "%d.%m.%Y %H:%M:%S", localtime(&val));
    return buff;
}

void greetDirectory(char * baseDir, char * modDir)
{
    DIR * directory;
    struct dirent * dirInfo;

    directory = opendir(baseDir);
    if (directory == NULL)
    {
        fprintf(stderr,
            "opendir() failed for '%s', errno=%d\n",
            baseDir,
            errno);
        exit(E_OPENDIRFAIL);
    }

    while((dirInfo = readdir(directory)) != NULL)
    {
        if (strcmp(dirInfo->d_name, ".") != 0 &&
            strcmp(dirInfo->d_name, "..") != 0)
        {
            /* BASE DIR*/
            char basePathName[PATH_MAX];
            strcpy(basePathName, baseDir);
            strcat(basePathName, "/");
            strcat(basePathName, dirInfo->d_name);

            /* MOD DIR */
            char modPathName[PATH_MAX];
            strcpy(modPathName, modDir);
            strcat(modPathName, "/");
            strcat(modPathName, dirInfo->d_name);

            struct stat statBuf;
            struct stat otherStatBuf;
            if (stat(basePathName, &statBuf) == -1)
            {
                /* error! */
                fprintf(stderr, "stat() failed for '%s'", basePathName);
            }
            else
            {
                //display time
                stat(modPathName, &otherStatBuf);
                if (statBuf.st_mtime > otherStatBuf.st_mtime)
                {
                    char date[36];
                    printf("Modify: %s\n", formatdate(date, otherStatBuf.st_mtime));
                }

                if (S_ISDIR(statBuf.st_mode))
                {
                    /* if this is a directory, then recurse! */
                    greetDirectory(basePathName, modPathName);
                }
                else
                {
                    /* else if it's a file, then greet it! */
                    printf("entry name = %s\n", modPathName);
                }
            }
        }
    }

    closedir(directory);    
}

The main problem was in your loop where you assign values to modDir and baseDir. Say, for example, you have the argument -R, so you want to print out the directory names. You assign R_switch a value of 1 since argv[1] is -R. The problem is, you go on in the loop to assign baseDir and modDir -R as well! This should have been done on the next iteration of the loop, when argv[2] is whatever directory you put in for input.

The very simple way to solve this problem is to add a continue; statement after you set R_switch a value of 1.


Also note that while playing around, I did create the limitation of having a MAX_DIR_NAME_SIZE, when it was not needed with the char * you were working with originally. It should be fairly easy to change this back. I also ended up changing the comparison of modDir and baseDir to something like if (baseDir[0] == 0 && modDir[0] == 0), which probably should have still been done by comparing your char * to NULL (like it was originally).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.