Skip to content

Commit

Permalink
Added No Follow symlink option to chown and chmod
Browse files Browse the repository at this point in the history
Enable symlink to not follow target file if "-h" option is
provided.

CRs-fixed: 545883
Change-Id: Iefd490bdd12cbe4cf9011f4b9b5e217493b2b503
  • Loading branch information
Biswajit Paul authored and broodplank committed Dec 23, 2013
1 parent 6258729 commit 3e1fee6
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 24 deletions.
81 changes: 64 additions & 17 deletions toolbox/chmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@

#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <getopt.h>

void recurse_chmod(char* path, int mode)
void recurse_chmod(char* path, int mode, unsigned int flag)
{
struct dirent *dp;
DIR *dir = opendir(path);
int fd = 0;
if (dir == NULL) {
// not a directory, carry on
return;
Expand All @@ -30,16 +33,23 @@ void recurse_chmod(char* path, int mode)
exit(1);
}

strcpy(subpath, path);
strcat(subpath, "/");
strcat(subpath, dp->d_name);

if (chmod(subpath, mode) < 0) {
fprintf(stderr, "Unable to chmod %s: %s\n", subpath, strerror(errno));
strlcpy(subpath, path, sizeof(subpath));
strlcat(subpath, "/", sizeof(subpath));
strlcat(subpath, dp->d_name, sizeof(subpath));

if(((fd = open(subpath, flag|O_RDONLY)) != -1) || ((fd = open(subpath, flag|O_WRONLY)) != -1)) {
if (fchmod(fd, mode) < 0){
fprintf(stderr, "Unable to chmod %s: %s\n", subpath, strerror(errno));
close(fd);
exit(1);
}
close(fd);
} else {
fprintf(stderr, "Unable to open %s: %s\n", subpath, strerror(errno));
exit(1);
}

recurse_chmod(subpath, mode);
recurse_chmod(subpath, mode, flag);
}
free(subpath);
closedir(dir);
Expand All @@ -49,6 +59,7 @@ static int usage()
{
fprintf(stderr, "Usage: chmod [OPTION] <MODE> <FILE>\n");
fprintf(stderr, " -R, --recursive change files and directories recursively\n");
fprintf(stderr, " -h, --no-dereference do not follow symlink\n");
fprintf(stderr, " --help display this help and exit\n");

return 10;
Expand All @@ -57,14 +68,36 @@ static int usage()
int chmod_main(int argc, char **argv)
{
int i;
int noFollow = 0;
int fd = 0;
int ch = 0;
int recursive = 0;
unsigned int flag =0;
static struct option long_options[] =
{
{"help", no_argument, 0, 'H'},
{"recursive", no_argument, 0, 'R'},
{"no-dereference", no_argument, 0, 'h'}
};
/* getopt_long stores the option index here. */
int option_index = 0;
while((ch = getopt_long(argc, argv, "HhR",long_options,&option_index)) != -1)
switch(ch){
case 'H':
if(argc < 3)
return usage();
break;
case 'R':
recursive = 1;
break;
case 'h':
noFollow = 1;
break;
default:
break;

if (argc < 3 || strcmp(argv[1], "--help") == 0) {
return usage();
}

int recursive = (strcmp(argv[1], "-R") == 0 ||
strcmp(argv[1], "--recursive") == 0) ? 1 : 0;

if (recursive && argc < 4) {
return usage();
}
Expand All @@ -73,7 +106,15 @@ int chmod_main(int argc, char **argv)
argc--;
argv++;
}
if (noFollow && argc < 4) {
return usage();
}

if(noFollow) {
flag = O_NOFOLLOW;
argc--;
argv++;
}
int mode = 0;
const char* s = argv[1];
while (*s) {
Expand All @@ -88,14 +129,20 @@ int chmod_main(int argc, char **argv)
}

for (i = 2; i < argc; i++) {
if (chmod(argv[i], mode) < 0) {
fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno));
if(((fd = open(argv[i], flag|O_RDONLY )) != -1)||((fd = open(argv[i], flag|O_WRONLY )) != -1)) {
if (fchmod(fd, mode) < 0){
fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno));
close(fd);
return 10;
}
close(fd);
} else {
fprintf(stderr, "Unable to open %s: %s\n", argv[i], strerror(errno));
return 10;
}
if (recursive) {
recurse_chmod(argv[i], mode);
recurse_chmod(argv[i], mode, flag);
}
}
return 0;
}

41 changes: 34 additions & 7 deletions toolbox/chown.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,40 @@

#include <unistd.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>

static int usage()
{
fprintf(stderr, "Usage: chown [OPTION] <USER>[:GROUP] <FILE1> [FILE2] ...\n");
fprintf(stderr, " -h: do not follow symlink\n");
return 10;
}

int chown_main(int argc, char **argv)
{
int i;
int fd = 0;
unsigned int flag = 0;

if (argc < 3) {
fprintf(stderr, "Usage: chown <USER>[:GROUP] <FILE1> [FILE2] ...\n");
return 10;
return usage();
}

// Copy argv[1] to 'user' so we can truncate it at the period
// if a group id specified.
char user[32];
char *group = NULL;
int noFollow = (strcmp(argv[1], "-h") == 0);
if (noFollow && argc < 4) {
return usage();
}
if(noFollow) {
flag = O_NOFOLLOW;
argc--;
argv++;
}

strncpy(user, argv[1], sizeof(user));
if ((group = strchr(user, ':')) != NULL) {
*group++ = '\0';
Expand All @@ -43,8 +63,8 @@ int chown_main(int argc, char **argv)
char* endptr;
uid = (int) strtoul(user, &endptr, 0);
if (endptr == user) { // no conversion
fprintf(stderr, "No such user '%s'\n", user);
return 10;
fprintf(stderr, "No such user '%s'\n", user);
return 10;
}
}

Expand All @@ -63,9 +83,16 @@ int chown_main(int argc, char **argv)
}

for (i = 2; i < argc; i++) {
if (chown(argv[i], uid, gid) < 0) {
fprintf(stderr, "Unable to chown %s: %s\n", argv[i], strerror(errno));
return 10;
if(((fd = open(argv[i], flag|O_RDONLY)) != -1) ||((fd = open(argv[i], flag|O_WRONLY)) != -1)){
if (fchown(fd, uid, gid) < 0){
fprintf(stderr, "Unable to chown %s: %s\n", argv[i], strerror(errno));
close(fd);
return 10;
}
close(fd);
} else {
fprintf(stderr, "Unable to open %s: %s\n", argv[i], strerror(errno));
return 10;
}
}

Expand Down

0 comments on commit 3e1fee6

Please sign in to comment.