1*18474Smckusick static char *sccsid = "@(#)chown.c 4.5 (Berkeley) 03/20/85"; 218450Smckusick 3975Sbill /* 4*18474Smckusick * 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> 1218450Smckusick #include <sys/dir.h> 1318450Smckusick #include <grp.h> 14975Sbill 15975Sbill struct passwd *pwd,*getpwnam(); 16975Sbill struct stat stbuf; 17975Sbill int uid; 18975Sbill int status; 1918450Smckusick int fflag, rflag; 20975Sbill 21975Sbill main(argc, argv) 22975Sbill char *argv[]; 23975Sbill { 2418450Smckusick register int c, gid; 2518450Smckusick register char *flags, *group; 2618450Smckusick struct group *grp; 27975Sbill 28975Sbill if(argc < 3) { 29*18474Smckusick fprintf(stderr, "usage: chown [-fR] owner[.group] file ...\n"); 3018450Smckusick exit(-1); 31975Sbill } 3218450Smckusick if (*argv[1] == '-') { 3318450Smckusick for (flags = argv[1]; *flags; ++flags) 3418450Smckusick switch (*flags) { 3518450Smckusick case '-': break; 3618450Smckusick case 'f': fflag++; break; 3718450Smckusick case 'R': rflag++; break; 3818450Smckusick default: 3918450Smckusick printf("chown: unknown option: %c\n", *flags); 4018450Smckusick exit(-2); 4118450Smckusick } 4211442Smckusick argv++, argc--; 4311442Smckusick } 4418450Smckusick 4518450Smckusick for (group = argv[1]; *group ; group++) { 4618450Smckusick if (*group == '.') { 4718450Smckusick *group = '\0'; 4818450Smckusick group++; 4918450Smckusick if (isnumber(group)) 5018450Smckusick gid = atoi(group); 5118450Smckusick else { 5218450Smckusick if ((grp=getgrnam(group)) == NULL) { 5318450Smckusick printf("unknown group: %s\n",group); 5418450Smckusick exit(-3); 5518450Smckusick } 5618450Smckusick gid = grp -> gr_gid; 5718450Smckusick endgrent(); 5818450Smckusick } 5918450Smckusick goto owner; 6018450Smckusick } 6118450Smckusick } 6218450Smckusick group = NULL; 6318450Smckusick 6418450Smckusick owner: 6518450Smckusick if (isnumber(argv[1])) { 66975Sbill uid = atoi(argv[1]); 6718450Smckusick } else { 6818450Smckusick if ((pwd=getpwnam(argv[1])) == NULL) { 6918450Smckusick printf("unknown user id: %s\n",argv[1]); 7018450Smckusick exit(-4); 7118450Smckusick } 7218450Smckusick uid = pwd->pw_uid; 73975Sbill } 74975Sbill 75975Sbill for(c=2; c<argc; c++) { 7618450Smckusick if (lstat(argv[c], &stbuf) < 0) { 7718450Smckusick printf("chown: couldn't stat %s\n", argv[c]); 7818450Smckusick exit(-5); 7918450Smckusick } 8018450Smckusick if (group == NULL) 8118450Smckusick gid = stbuf.st_gid; 8218450Smckusick if (rflag && stbuf.st_mode & S_IFDIR) 8318450Smckusick status += chownr(argv[c], group, uid, gid); 8418450Smckusick else if (chown(argv[c], uid, gid) < 0 && !fflag) { 85975Sbill perror(argv[c]); 8618450Smckusick 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 } 10218450Smckusick 10318450Smckusick chownr(dir, dogrp, uid, gid_save) 10418450Smckusick char *dir; 10518450Smckusick { 10618450Smckusick register DIR *dirp; 10718450Smckusick register struct direct *dp; 10818450Smckusick register struct stat st; 10918450Smckusick char savedir[1024]; 11018450Smckusick int gid; 11118450Smckusick 11218450Smckusick if (getwd(savedir) == 0) { 11318450Smckusick fprintf(stderr, "chown: %s\n", savedir); 11418450Smckusick exit(-6); 11518450Smckusick } 11618450Smckusick if (chown(dir, uid, gid_save) < 0 && !fflag) { 11718450Smckusick perror(dir); 11818450Smckusick return(1); 11918450Smckusick } 12018450Smckusick 12118450Smckusick chdir(dir); 12218450Smckusick if ((dirp = opendir(".")) == NULL) { 12318450Smckusick perror(dir); 12418450Smckusick exit(status); 12518450Smckusick } 12618450Smckusick dp = readdir(dirp); 12718450Smckusick dp = readdir(dirp); /* read "." and ".." */ 12818450Smckusick 12918450Smckusick for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 13018450Smckusick if (lstat(dp->d_name, &st) < 0) { 13118450Smckusick fprintf(stderr, "chown: can't access %s\n", dp->d_name); 13218450Smckusick return(1); 13318450Smckusick } 13418450Smckusick if (dogrp) 13518450Smckusick gid = gid_save; 13618450Smckusick else 13718450Smckusick gid = st.st_gid; 13818450Smckusick if (st.st_mode & S_IFDIR) 13918450Smckusick chownr(dp->d_name, dogrp, uid, gid); 14018450Smckusick else 14118450Smckusick if (chown(dp->d_name, uid, gid) < 0 && !fflag) { 14218450Smckusick perror(dp->d_name); 14318450Smckusick return(1); 14418450Smckusick } 14518450Smckusick } 14618450Smckusick closedir(dirp); 14718450Smckusick chdir(savedir); 14818450Smckusick return(0); 14918450Smckusick } 150