give: change owner/group of files
sources-request at panda.UUCP
sources-request at panda.UUCP
Fri Nov 15 11:59:45 AEST 1985
Mod.sources: Volume 3, Issue 44
Submitted by: philabs!mcnc!ikonas!!roger
[ moderators note: This program ONLY works properly on System III/V
where chown(3) allows you to give away ownership of a file. It might
be useful to superusers on V7/BSD type systems, perhaps?
]
Wednesday, 13 November 1985, 5:32 p.m.
Enclosed find the manual page and C source for a program
to change owner and group id's for one or more files. If
a named file is a directory, the entire tree beginning
with (and including) that directory is descended and changed.
Roger L. Cordes, Jr.
William G. Daniel & Associates
...!mcnc!ikonas!dedalus!roger
#!/bin/sh
# This is a shar archive: extract with sh, not csh.
# This archive contains:
# give.1
# give.c
echo x - give.1
cat > give.1 << '!Funky!Stuff!'
.TH GIVE sd
.SH NAME
give \- change owner and group information for one or more files
.SH SYNOPSIS
.B give
.I file...
.B to
.I user
[\c
.I group\c
]
.SH DESCRIPTION
.B Give
will change ownership and group information for the files specified.
If any of the files is a directory,
.B give
will descend and change the entire directory tree, including the named
directory.
.sp
AS might be expected,
.B give
will only work for the current owner of the named files or root.
.SH DIAGNOSTICS
.B Give
will exit with a descriptive error message if any of the
following occur:
.br
.in +0.5i
access to /etc/passwd (and /etc/group, if applicable) is denied
.br
the named user (group) does not occur in the file
.br
files specified cannot be accessed or modified
.in -0.5i
.SH FILES
/etc/passwd \- user list
.br
/etc/group \- group list
.br
!Funky!Stuff!
echo x - give.c
cat > give.c << '!Funky!Stuff!'
#
/****
**** Wednesday, 13 November 1985, 1:29 p.m.
**** give: change owner and group for one or more files as indicated:
**** usage:
**** give file... to user [group]
**** - may be used succesfully only by current owner or root
**** - if file is a directory, descend and change the entire tree
**** beginning with (including) the named directory
**** compile:
**** cc -O -o give give.c
****/
main(argc,argv)
int argc;
char *argv[];
{
int i, to, uid = -1, gid = -1;
/*
* find end of filename list in argv[] and verify command-line syntax:
* must say at least: "give SOMETHING to SOMEBODY"
*/
for ( i=0; i<argc; i++ )
if ( !strcmp(argv[i],"to") )
{
to = i;
break;
}
if ( (argc<4) || (to<2) || (to==(argc-1)) || (argc<4) )
exit(printf("usage: %s File... to User [Group]\n",argv[0]));
/*
* get target integer user id
*/
if ( (uid=getuser(argv[to+1])) < 0 )
exit(printf("unknown user: `%s'...\n",argv[to+1]));
/*
* get target integer group id (if applicable)
*/
if ( (to<(argc-2)) && ((gid=getgroup(argv[to+2]))<0) )
exit(printf("unknown group: `%s'...\n",argv[to+2]));
give(&argv[1],(to-1),uid,gid,0);
}
#include <stdio.h>
/*
* getuser: get integer user id: returns -1 if unknown
*/
#define is_digit(C) ( ((C)>='0') && ((C)<='9') )
char line[256], *c = (char *)0, *strchr();
getuser(name)
char *name;
{
FILE *file;
int uid = -1, i, len, strlen(), intname = 1;
len = strlen(name);
for ( i=0; i<len; i++ )
if ( !is_digit(name[i]) )
intname = 0;
if ( !(file=fopen("/etc/passwd","r")) )
exit(printf("cannot read user name list...\n"));
while ( fgets(line,128,file) )
if ( intname || !strncmp(line,name,len) )
{
c = line;
for ( i=0; i<2; i++ )
if ( !(c=strchr((c+1),':')) )
if ( intname )
break;
else
goto out;
if ( !intname || !strncmp((c+1),name,len) )
{
sscanf((c+1),"%d",&uid);
break;
}
}
out:
fclose(file);
return(uid);
}
/*
* getgroup: get integer group id: returns -1 on error
*/
getgroup(name)
char *name;
{
int i, gid = -1, intname = 1, len;
FILE *file;
len = strlen(name);
for ( i=0; i<len; i++ )
if ( !is_digit(name[i]) )
intname = 0;
if ( !(file=fopen("/etc/group","r")) )
return(-1);
while ( fgets(line,128,file) )
if ( intname || !strncmp(line,name,len) )
{
if ( !(c=strchr(line,':')) )
goto out;
if ( !(c=strchr((c+1),':')) )
goto out;
if ( intname && strncmp((c+1),name,len) )
continue;
sscanf((c+1),"%d",&gid);
}
out:
fclose(file);
return(gid);
}
/*
* give: recursively descend a directory structure changing
* owner and group ids.
*/
#include <sys/types.h>
#include <sys/stat.h>
#define indent() for ( j=0; j<pass; j++ ) printf(" ")
#define is_dir() ((st.st_mode&S_IFDIR)==S_IFDIR)
give(names,n,uid,gid,pass)
char **names;
int n, uid, gid, pass;
{
int i, j, grp, nn = 0, stat();
struct stat st;
char **next;
for ( i=0; i<n; i++ )
{
if ( stat(names[i],&st) < 0 )
{
indent();
printf("`%s': cannot stat...\n",names[i]);
continue;
}
if ( gid < 0 )
grp = st.st_gid;
else
grp = gid;
if ( is_dir() )
{
indent();
printf("%s:\n",names[i]);
if ( chdir(names[i]) < 0 )
{
indent();
printf("cannot cd to `%s'...\n",
names[i]);
continue;
}
if ( !(nn=getflist(&next)) )
{
indent();
printf("cannot ls `%s'...\n",names[i]);
}
else
give(next,nn,uid,gid,(pass+1));
if ( chdir("..") < 0 )
{
indent();
printf("cannot cd to `..'...\n");
exit(3);
}
}
if ( chown(names[i],uid,grp) < 0 )
{
indent();
printf("`%s': cannot change...\n",names[i]);
}
}
}
/*
* getflist: get names of files in current working directory
*/
#include <sys/dir.h>
char ln[4096], *strcat();
getflist(names)
char ***names;
{
int n = 0;
struct direct dir;
FILE *file;
if ( !(file=fopen(".","r")) )
return(0);
ln[0] = 0;
while ( fread(&dir,sizeof(struct direct),1,file) )
if ( !strcmp(dir.d_name,".") || !strcmp(dir.d_name,"..") )
continue;
else if ( dir.d_ino )
{
strcat(ln,dir.d_name);
strcat(ln," ");
}
fclose(file);
n = get_words(ln,names);
return(n);
}
/*
* get_words: split a character string into individual words
*/
#define is_white(C) ( ((C)==' ') || ((C)=='\t') )
int get_words(line,wordlist)
char *line;
char ***wordlist;
{
int i, j, k, nwords = 0, len = 0, longest = 0;
char *c, **words, *malloc(), was_white = 0, got_a_word = 0;
/*
* count words, find longest word
*/
for ( c=line; *c; c++ )
if ( is_white(*c) )
{
if ( got_a_word && !was_white )
{
if ( len > longest )
longest = len;
len = 0;
nwords++;
}
was_white = 1;
}
else
{
was_white = 0;
got_a_word = 1;
len++;
}
if ( got_a_word && !was_white )
{
if ( len > longest )
longest = len;
len = 0;
nwords++;
}
if ( !nwords )
return(0);
/*
* allocate the array of individual words
*/
if ( !(words=(char **)malloc(nwords*sizeof(char *))) )
{
printf("cannot create the word list...\n");
return(0);
}
longest++; /* plus '\0' */
for ( i=0; i<nwords; i++ )
if ( (words[i]=malloc(longest*sizeof(char))) == NULL )
{
printf("cannot allocate an individual word...\n");
for ( --i; i>=0; i-- )
free(words[i]);
free((char *)words);
return(0);
}
/*
* load the array of individual words
*/
got_a_word = was_white = j = k = 0;
for ( i=0; line[i]!='\0'; i++ )
if ( !is_white(line[i]) )
{
got_a_word = 1;
words[j][k] = line[i];
was_white = 0;
k++;
}
else if ( got_a_word && !was_white )
{
words[j][k] = '\0';
was_white = 1;
k = 0;
j++;
}
if ( got_a_word && !was_white )
words[j][k] = '\0';
*wordlist = words;
return(nwords);
}
!Funky!Stuff!
More information about the Mod.sources
mailing list