0

I am new in c programming. How can I change directory like /home/jobs/$ans/xxx/ while I have $ans is a user string I can't chdir in c program.

My script is below:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char jdir;
    printf("Enter job directory:");  /* user input for different directories */
    scanf("jdir");
    chdir("/home/jobs/%jdir/xxx");
    system("ls -ltr");
    return(0);
}

How to change directory with chdir?

jww
  • 97,681
  • 90
  • 411
  • 885
user1795444
  • 1
  • 1
  • 1
  • 1

2 Answers2

2

Use something like:

char jdir[200]
scanf("%s", &jdir);
char blah[200];
snprintf(blah, 199, "/home/jobs/%s/xxx", jdir);
chdir(blah);
solarised
  • 114
  • 2
  • 1
    `snprintf(blah, sizeof(blah), ...)` is the standard idiom. You don't have to reserve an extra character over the number specified in the call. OTOH, you could/should use `if (scanf("%199s", jdir) != 1)`, correcting the `&jdir` (same value, different type) and ensuring that the string is not overrun (and there 199 is correct; you have to allocate the extra character). _And_ (like @cHao said), you need more space in `blah` if the user types a lot of characters into `jdir`. In fact, `blah` should be at least 15 characters longer than `jdir`. – Jonathan Leffler Nov 03 '12 at 00:18
  • 1
    Just so it's said, you might want to adjust those buffer sizes. If i were to type in "../jobs/./././(87+ more ./'s)", looks like that'll put me in /home/jobs. (Yeah, i'm bored.) `blah` should be big enough to account for the input size plus known text, at least. – cHao Nov 03 '12 at 00:19
  • 1
    `scanf("%s")` is every bit as unsafe as `gets`. – zwol Jul 02 '16 at 14:25
2

It seems mildly silly to write this program in C, but if there is a good reason to do so (for instance if it has to be setuid) then you should be a great deal more defensive about it. I would do something like this:

#define _XOPEN_SOURCE 700 /* getline */
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(void)
{
    char *jobdir = 0;
    size_t asize = 0;
    ssize_t len;

    fputs("Enter job directory: ", stdout);
    fflush(stdout);
    len = getline(&jobdir, &asize, stdin);
    if (len < 0) {
        perror("getline");
        return 1;
    }

    jobdir[--len] = '\0'; /* remove trailing \n */
    if (len == 0 || !strcmp(jobdir, ".") || !strcmp(jobdir, "..")
        || strchr(jobdir, '/')) {
        fputs("job directory name may not be empty, \".\", or \"..\", "
              "nor contain a '/'\n", stderr);
        return 1;
    }

    if (chdir("/home/jobs") || chdir(jobdir) || chdir("xxx")) {
        perror(jobdir);
        return 1;
    }
    execlp("ls", "ls", "-ltr", (char *)0);
    perror("exec");
    return 1;
}

The edit history of this answer will demonstrate just how hard it is to get this 100% right - I keep coming back to it and realizing that I forgot yet another case that needs to be defended against.

zwol
  • 135,547
  • 38
  • 252
  • 361