--- sysctl.c +++ sysctl.c 2008-02-14 12:04:36.000000000 +0100 @@ -128,6 +128,7 @@ static int ReadSetting(const char *restr char *restrict outname; char inbuf[1025]; FILE *restrict fp; + struct stat ts; if (!name || !*name) { fprintf(stderr, ERR_INVALID_KEY, name); @@ -144,6 +145,23 @@ static int ReadSetting(const char *restr outname = strdup(name); slashdot(outname,'/','.'); /* change / to . */ + if (stat(tmpname, &ts) < 0) { + perror(tmpname); + rc = -1; + goto out; + } + if ((ts.st_mode & S_IRUSR) == 0) + goto out; + + if (S_ISDIR(ts.st_mode)) { + size_t len; + len = strlen(tmpname); + tmpname[len] = '/'; + tmpname[len+1] = '\0'; + rc = DisplayAll(tmpname); + goto out; + } + fp = fopen(tmpname, "r"); if (!fp) { @@ -164,6 +182,7 @@ static int ReadSetting(const char *restr break; } } else { + errno = 0; if(fgets(inbuf, sizeof inbuf - 1, fp)) { // this loop is required, see // /sbin/sysctl -a | egrep -6 dev.cdrom.info @@ -194,18 +213,20 @@ static int ReadSetting(const char *restr len = strlen(tmpname); tmpname[len] = '/'; tmpname[len+1] = '\0'; + fclose(fp); rc = DisplayAll(tmpname); - break; + goto out; } default: fprintf(stderr, ERR_UNKNOWN_READING, strerror(errno), outname); rc = -1; + case 0: break; } } fclose(fp); } - +out: free(tmpname); free(outname); return rc; @@ -265,8 +286,9 @@ static int WriteSetting(const char *sett const char *value; const char *equals; char *tmpname; - FILE *fp; char *outname; + FILE *fp; + struct stat ts; if (!name) { /* probably don't want to display this err */ return 0; @@ -299,6 +321,22 @@ static int WriteSetting(const char *sett outname[equals-name] = 0; slashdot(outname,'/','.'); /* change / to . */ + if (stat(tmpname, &ts) < 0) { + perror(tmpname); + rc = -1; + goto out; + } + + if ((ts.st_mode & S_IWUSR) == 0) { + fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname); + goto out; + } + + if (S_ISDIR(ts.st_mode)) { + fprintf(stderr, ERR_UNKNOWN_WRITING, strerror(EACCES), outname); + goto out; + } + fp = fopen(tmpname, "w"); if (!fp) { @@ -343,7 +381,7 @@ static int WriteSetting(const char *sett } } } - +out: free(tmpname); free(outname); return rc;