1*18450Smckusick static char *sccsid = "@(#)chown.c 4.4 (Berkeley) 03/20/85"; 2*18450Smckusick 3975Sbill /* 4*18450Smckusick * chown [-fr] uid[.gid] file ... 5975Sbill */ 6975Sbill 7975Sbill #include <stdio.h> 8975Sbill #include <ctype.h> 9975Sbill #include <sys/types.h> 10975Sbill #include <sys/stat.h> 11975Sbill #include <pwd.h> 12*18450Smckusick #include <sys/dir.h> 13*18450Smckusick #include <grp.h> 14975Sbill 15975Sbill struct passwd *pwd,*getpwnam(); 16975Sbill struct stat stbuf; 17975Sbill int uid; 18975Sbill int status; 19*18450Smckusick int fflag, rflag; 20975Sbill 21975Sbill main(argc, argv) 22975Sbill char *argv[]; 23975Sbill { 24*18450Smckusick register int c, gid; 25*18450Smckusick register char *flags, *group; 26*18450Smckusick struct group *grp; 27975Sbill 28975Sbill if(argc < 3) { 29*18450Smckusick fprintf(stderr, "usage: chown [-fr] uid[.gid] file ...\n"); 30*18450Smckusick exit(-1); 31975Sbill } 32*18450Smckusick if (*argv[1] == '-') { 33*18450Smckusick for (flags = argv[1]; *flags; ++flags) 34*18450Smckusick switch (*flags) { 35*18450Smckusick case '-': break; 36*18450Smckusick case 'f': fflag++; break; 37*18450Smckusick case 'R': rflag++; break; 38*18450Smckusick default: 39*18450Smckusick printf("chown: unknown option: %c\n", *flags); 40*18450Smckusick exit(-2); 41*18450Smckusick } 4211442Smckusick argv++, argc--; 4311442Smckusick } 44*18450Smckusick 45*18450Smckusick for (group = argv[1]; *group ; group++) { 46*18450Smckusick if (*group == '.') { 47*18450Smckusick *group = '\0'; 48*18450Smckusick group++; 49*18450Smckusick if (isnumber(group)) 50*18450Smckusick gid = atoi(group); 51*18450Smckusick else { 52*18450Smckusick if ((grp=getgrnam(group)) == NULL) { 53*18450Smckusick printf("unknown group: %s\n",group); 54*18450Smckusick exit(-3); 55*18450Smckusick } 56*18450Smckusick gid = grp -> gr_gid; 57*18450Smckusick endgrent(); 58*18450Smckusick } 59*18450Smckusick goto owner; 60*18450Smckusick } 61*18450Smckusick } 62*18450Smckusick group = NULL; 63*18450Smckusick 64*18450Smckusick owner: 65*18450Smckusick if (isnumber(argv[1])) { 66975Sbill uid = atoi(argv[1]); 67*18450Smckusick } else { 68*18450Smckusick if ((pwd=getpwnam(argv[1])) == NULL) { 69*18450Smckusick printf("unknown user id: %s\n",argv[1]); 70*18450Smckusick exit(-4); 71*18450Smckusick } 72*18450Smckusick uid = pwd->pw_uid; 73975Sbill } 74975Sbill 75975Sbill for(c=2; c<argc; c++) { 76*18450Smckusick if (lstat(argv[c], &stbuf) < 0) { 77*18450Smckusick printf("chown: couldn't stat %s\n", argv[c]); 78*18450Smckusick exit(-5); 79*18450Smckusick } 80*18450Smckusick if (group == NULL) 81*18450Smckusick gid = stbuf.st_gid; 82*18450Smckusick if (rflag && stbuf.st_mode & S_IFDIR) 83*18450Smckusick status += chownr(argv[c], group, uid, gid); 84*18450Smckusick else if (chown(argv[c], uid, gid) < 0 && !fflag) { 85975Sbill perror(argv[c]); 86*18450Smckusick status++; 87975Sbill } 88975Sbill } 89975Sbill exit(status); 90975Sbill } 91975Sbill 92975Sbill isnumber(s) 93975Sbill char *s; 94975Sbill { 95975Sbill register c; 96975Sbill 97975Sbill while(c = *s++) 98975Sbill if(!isdigit(c)) 99975Sbill return(0); 100975Sbill return(1); 101975Sbill } 102*18450Smckusick 103*18450Smckusick chownr(dir, dogrp, uid, gid_save) 104*18450Smckusick char *dir; 105*18450Smckusick { 106*18450Smckusick register DIR *dirp; 107*18450Smckusick register struct direct *dp; 108*18450Smckusick register struct stat st; 109*18450Smckusick char savedir[1024]; 110*18450Smckusick int gid; 111*18450Smckusick 112*18450Smckusick if (getwd(savedir) == 0) { 113*18450Smckusick fprintf(stderr, "chown: %s\n", savedir); 114*18450Smckusick exit(-6); 115*18450Smckusick } 116*18450Smckusick if (chown(dir, uid, gid_save) < 0 && !fflag) { 117*18450Smckusick perror(dir); 118*18450Smckusick return(1); 119*18450Smckusick } 120*18450Smckusick 121*18450Smckusick chdir(dir); 122*18450Smckusick if ((dirp = opendir(".")) == NULL) { 123*18450Smckusick perror(dir); 124*18450Smckusick exit(status); 125*18450Smckusick } 126*18450Smckusick dp = readdir(dirp); 127*18450Smckusick dp = readdir(dirp); /* read "." and ".." */ 128*18450Smckusick 129*18450Smckusick for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 130*18450Smckusick if (lstat(dp->d_name, &st) < 0) { 131*18450Smckusick fprintf(stderr, "chown: can't access %s\n", dp->d_name); 132*18450Smckusick return(1); 133*18450Smckusick } 134*18450Smckusick if (dogrp) 135*18450Smckusick gid = gid_save; 136*18450Smckusick else 137*18450Smckusick gid = st.st_gid; 138*18450Smckusick if (st.st_mode & S_IFDIR) 139*18450Smckusick chownr(dp->d_name, dogrp, uid, gid); 140*18450Smckusick else 141*18450Smckusick if (chown(dp->d_name, uid, gid) < 0 && !fflag) { 142*18450Smckusick perror(dp->d_name); 143*18450Smckusick return(1); 144*18450Smckusick } 145*18450Smckusick } 146*18450Smckusick closedir(dirp); 147*18450Smckusick chdir(savedir); 148*18450Smckusick return(0); 149*18450Smckusick } 150