ch2-chown

Chapter_2     open readfile







chown.c     ALP, p. 41


#include <stdio.h> // printf(), scanf(), fprintf(), stderr
#include <string.h> // for strerror()
#include <stdlib.h> // for exit(), abort()
#include <assert.h> // for assert()
#include <errno.h> // for errno macro
/*
errno.h includes x86_64-linux-gnu/bits/errno,h, which includes
linux/errno.h, which includes asm-generic/errno.h, which includes
asm-generic/errno-base.h, which defines:
#define EPERM 1 // Operation not permitted
#define ENOENT 2 // No such file or directory
#define EINTR 4 // Interrupted system call
#define EIO 5 // I/O error
#define ENOMEM 12 // Out of memory
#define EACCES 13 // Permission denied
#define EFAULT 14 // Bad address
#define ENOTDIR 20 // Not a directory
#define EINVAL 22 // Invalid argument
#define EROFS 30 // Read-only file system
asm-generic/errno.h defines:
#define ENAMETOOLONG 36 // File name too long
#define ELOOP 40 // Too many symbolic links encountered
*/
#include <unistd.h> // for chown(), getuid(), getgid()
#include <linux/limits.h> // for PATH_MAX, NAME_MAX
// #define NAME_MAX 255 /* # chars in a file name */
// #define PATH_MAX 4096 /* # chars in a path name including nul */
#include <sys/stat.h> // for struct stat, stat()
#include <sys/types.h> // uid_t, gid_t
#include <pwd.h> // for struct passwd, getpwuid()

char * getUser(uid_t uid)
{
struct passwd *pws;
pws = getpwuid(uid);

return pws->pw_name;
}

int main()
{
char path[PATH_MAX];
int rval; // return value
struct stat s;
uid_t uid;
gid_t gid;

printf("Path: ");
scanf("%s", path);
uid = getuid();
gid = getgid();
printf("User ID: %d (%s)\n", uid, getUser(uid));
printf("Group ID: %d\n", gid);
rval = chown(path, uid, gid);

if (rval != 0)
{ /* Save errno because it's clobbered by the next system call: */
int error_code = errno;
/* The operation didn't succeed; chown() should return -1 on error: */
assert(rval == -1);
/* Check the value of errno, and take appropriate action: */
switch (error_code)
{
case EPERM: /* Permission denied. */
case EROFS: /* PATH is on a read-only file system. */
case EACCES: /* A component of PATH is not accessible. */
if (stat(path, &s) != -1)
{
printf("File user ID: %d (%s)\n", s.st_uid, getUser(s.st_uid));
printf("File group ID: %d\n", s.st_gid);
}
case ENAMETOOLONG: /* PATH is too long. */
case ENOENT: /* PATH does not exist. */
case ENOTDIR: /* A component of PATH is not a directory. */
case EIO: // I/O error
case EINVAL: // Invalid argument
case ELOOP: // Too many symbolic links encountered
/* Something's wrong with the file. Print an error message: */
fprintf (stderr, "Error number: %d\n", error_code);
fprintf (stderr, "Error changing ownership of \"%s\": %s\n",
path, strerror (error_code));
/* Don't end the program; perhaps give the user a chance to
choose another file... */
break;
case EFAULT: // path contains invalid mem address, probably a bug
abort(); // used for debugging
case ENOMEM: /* Ran out of kernel memory. */
case EINTR: // Interrupted system call
fprintf (stderr, "%s\n", strerror (error_code));
exit(1); // no debugging
default: // unexpected error code, probably a bug
abort(); // used for debugging
}
}

return 0;
}
/*
gcc chown.c -o chown
./chown
Path: /home/user/.bash_history
User ID: 1000 (user)
Group ID: 1001
// No error

./chown
Path: /etc/environment
User ID: 1000 (user)
Group ID: 1001
File user ID: 0 (root)
File group ID: 0
Error number: 1
Error changing ownership of "/etc/environment": Operation not permitted
*/





Note:  See also File's_owner_name and getUser on StackOverflow.









Chapter_2     open BACK_TO_TOP readfile



Comments

Popular posts from this blog

Contents