static void set_attrs(CXmlNodePtr acl, const char *type, int deny, int noinherit) { acl->NewNode(type); if(deny) acl->NewAttribute("deny","1"); if(noinherit) acl->NewAttribute("inherit","0"); acl->GetParent(); }
int chacl_fileproc(void *callerdat, struct file_info *finfo) { CXmlNodePtr acl; /* If someone has specified 'chacl foo' and foo is a directory, you'll get a dirent plus every file in the directory. We only want to set the directory in this case */ if(acl_directory_set && !strcmp(finfo->repository, acl_directory_set)) return 0; Vers_TS *vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0, 0); if(!vers->vn_user && !vers->vn_rcs) { if (!really_quiet) error (0, 0, "nothing known about %s", fn_root(finfo->fullname)); freevers_ts(&vers); return 0; } freevers_ts(&vers); if(!quiet) printf("%sing ACL for file %s\n",parms.del?"delet":"sett",finfo->file); acl = fileattr_getroot(); acl->xpathVariable("name",finfo->file); if(!acl->Lookup("file[cvs:filename(@name,$name)]") || !acl->XPathResultNext()) { acl = fileattr_getroot(); acl->NewNode("file"); acl->NewAttribute("name",finfo->file); } set_acl(acl); return 0; }
static void set_acl(CXmlNodePtr base) { CXmlNodePtr acl, acl_to_set = NULL; acl = fileattr_find(base,"acl"); while(acl) { const char *user = fileattr_getvalue(acl,"@user"); const char *branch = fileattr_getvalue(acl,"@branch"); const char *merge = fileattr_getvalue(acl,"@merge"); if(((!user && !parms.user) || (user && parms.user && !usercmp(user,parms.user))) && ((!branch && !parms.branch) || (branch && parms.branch && !strcmp(branch,parms.branch))) && ((!merge && !parms.merge) || (merge && parms.merge && !strcmp(merge,parms.merge)))) { acl_to_set = acl; break; } acl = fileattr_next(acl); } if(acl_to_set) fileattr_batch_delete(acl_to_set); if(!parms.del) { char *parm = xstrdup(parms.access); char *acc = parm?strtok(parm,","):NULL; base->NewNode("acl"); fileattr_modified(); if(parms.user) base->NewAttribute("user",parms.user); if(parms.branch) base->NewAttribute("branch",parms.branch); if(parms.merge) base->NewAttribute("merge",parms.merge); if(parms.priority && atoi(parms.priority)) base->NewAttribute("priority",parms.priority); if(parms.message) base->NewNode("message",parms.message,false); base->NewNode("modified_by",getcaller(),false); base->NewNode("modified_date",current_date,false); while(acc) { int deny=0; if(!strncmp(acc,"no",2) && strcmp(acc,"none")) { deny=1; acc+=2; } if(!strcmp(acc,"all")) set_attrs(base,"all",deny,parms.noinherit); else if(!strcmp(acc,"none")) set_attrs(base,"all",!deny,parms.noinherit); else if(!strcmp(acc,"read")) set_attrs(base,"read",deny,parms.noinherit); else if(!strcmp(acc,"write")) set_attrs(base,"write",deny,parms.noinherit); else if(!strcmp(acc,"create")) set_attrs(base,"create",deny,parms.noinherit); else if(!strcmp(acc,"tag")) set_attrs(base,"tag",deny,parms.noinherit); else if(!strcmp(acc,"control")) set_attrs(base,"control",deny,parms.noinherit); else error(1,0,"Invalid access control attribute '%s'",acc); acc = strtok(NULL,","); } base->GetParent(); fileattr_prune(base); xfree(parm); } else { if(acl_to_set) fileattr_prune(acl_to_set); } }