#if HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "pattern.h" #include "pclt.h" #ifndef UINT8_MAX # define UINT8_MAX 255 #endif #ifndef UINT16_MAX # define UINT16_MAX 65535 #endif /* PCLENT */ static PCLENT * pclent_name_add(p, s) PCLENT *p; const char *s; { char **namep; if (UINT16_MAX<=p->pcl_namesize) { errno=ENOMEM; return (NULL); } namep=(char **)realloc(p->pcl_name, sizeof(char *)*(p->pcl_namesize+1)); if (!namep) return (NULL); if (!(namep[p->pcl_namesize]=(char *)strdup(s))) { free(namep); return (NULL); } p->pcl_name=namep; p->pcl_namesize++; return (p); } static PCLENT * pclent_name_copy(dst, src) PCLENT *dst; const PCLENT *src; { int i; dst->pcl_namesize=0; dst->pcl_name=NULL; if (src->pcl_name) { dst->pcl_namesize=src->pcl_namesize; dst->pcl_name=(char **)malloc( sizeof(char *)*(src->pcl_namesize)); if (!dst->pcl_name) return (NULL); for (i=0; ipcl_namesize; ++i) { dst->pcl_name[i]=(char *)strdup(src->pcl_name[i]); if (!dst->pcl_name[i]) return (NULL); } } return (dst); } static int pclent_name_match(p, s) const PCLENT *p; const char *s; { int i; for (i=0; ipcl_namesize; ++i) { if (pattern(p->pcl_name[i], s)!=0) return (1); } return (0); } static void pclent_name_clear(p) PCLENT *p; { int i; if (p->pcl_name) { for (i=0; ipcl_namesize; ++i) free(p->pcl_name[i]); free(p->pcl_name); p->pcl_name=NULL; p->pcl_namesize=0; } } PCLENT * pclent_addname(p, s) PCLENT *p; const char *s; { return (pclent_name_add(p, s)); } #if ENABLE_REGEX static PCLENT * pclent_ename_add(p, s, errval) PCLENT *p; const char *s; int *errval; { regex_t *enamep; char **patternp; if (UINT16_MAX<=p->pcl_enamesize) { errno=ENOMEM; return (NULL); } patternp=(char **)realloc(p->pcl_pattern, sizeof(char *)*(p->pcl_enamesize+1)); if (!patternp) return (NULL); if (!(patternp[p->pcl_enamesize]=(char *)strdup(s))) return (NULL); p->pcl_pattern=patternp; enamep=(regex_t *)realloc(p->pcl_ename, sizeof(regex_t)*(p->pcl_enamesize+1)); if (!enamep) return (NULL); *errval=regcomp(&enamep[p->pcl_enamesize], s, REG_NOSUB|REG_EXTENDED); if (*errval) return (NULL); p->pcl_ename=enamep; p->pcl_enamesize++; return (p); } static PCLENT * pclent_ename_copy(dst, src) PCLENT *dst; const PCLENT *src; { int i; dst->pcl_pattern=(char **)malloc(sizeof(char *)*(src->pcl_enamesize)); if (!dst->pcl_pattern) return (NULL); dst->pcl_ename=(regex_t *)malloc(sizeof(regex_t)*(src->pcl_enamesize)); if (!dst->pcl_ename) return (NULL); for (i=0; ipcl_enamesize; ++i) { dst->pcl_pattern[i]=(char *)strdup(src->pcl_pattern[i]); if (!dst->pcl_pattern[i]) return (NULL); if (regcomp(&dst->pcl_ename[i], src->pcl_pattern[i], REG_NOSUB|REG_EXTENDED)!=0) return (NULL); } dst->pcl_enamesize=src->pcl_enamesize; return (dst); } static int pclent_ename_match(p, s) const PCLENT *p; const char *s; { int i; for (i=0; ipcl_enamesize; ++i) { if (regexec(&p->pcl_ename[i], s, (size_t)0, NULL, 0)==0) return (1); } return (0); } static void pclent_ename_clear(p) PCLENT *p; { int i; if (p->pcl_ename) { for (i=0; ipcl_enamesize; ++i) { free(p->pcl_pattern[i]); regfree(&p->pcl_ename[i]); } free(p->pcl_pattern); p->pcl_pattern=NULL; free(p->pcl_ename); p->pcl_ename=NULL; p->pcl_enamesize=0; } } PCLENT * pclent_addename(p, s, errval) PCLENT *p; const char *s; int *errval; { return (pclent_ename_add(p, s, errval)); } #endif /* ENABLE_REGEX */ static PCLENT * pclent_egid_add(p, egid) PCLENT *p; PCLEGID *egid; { PCLEGID *egidp; if (UINT16_MAX<=p->pcl_egidsize) { errno=ENOMEM; return (NULL); } egidp=(PCLEGID *)realloc(p->pcl_egid, sizeof(PCLEGID)*(p->pcl_egidsize+1)); if (!egidp) return (NULL); p->pcl_egid=egidp; (void)memcpy(&p->pcl_egid[p->pcl_egidsize], egid, sizeof(PCLEGID)); p->pcl_egidsize++; return (p); } static PCLENT * pclent_egid_copy(dst, src) PCLENT *dst; const PCLENT *src; { dst->pcl_egid=(PCLEGID *)malloc(sizeof(PCLEGID)*(src->pcl_egidsize)); if (!dst->pcl_egid) return (NULL); (void)memcpy(dst->pcl_egid, src->pcl_egid, sizeof(PCLEGID)*(src->pcl_egidsize)); dst->pcl_egidsize = src->pcl_egidsize; return (dst); } static int pclent_egid_match(p, gid) const PCLENT *p; gid_t gid; { const PCLEGID *egid; int i; for (i=0; ipcl_egidsize; ++i) { egid=&p->pcl_egid[i]; switch (egid->pcl_type) { case PCLEGID_S: if (egid->pcl_lgid==gid) return (1); break; case PCLEGID_L: if (egid->pcl_lgid>=gid) return (1); break; case PCLEGID_R: if (gid<=egid->pcl_rgid) return (1); break; case PCLEGID_LR: if (egid->pcl_lgid<=gid && gid<=egid->pcl_rgid) return (1); break; } } return (0); } static void pclent_egid_clear(p) PCLENT *p; { if (p->pcl_egid) free(p->pcl_egid); p->pcl_egid=NULL; p->pcl_egidsize=0; } PCLENT * pclent_addegid(p, egid) PCLENT *p; PCLEGID *egid; { return (pclent_egid_add(p, egid)); } static PCLENT * pclent_euid_add(p, euid) PCLENT *p; PCLEUID *euid; { PCLEUID *euidp; if (UINT16_MAX<=p->pcl_euidsize) { errno=ENOMEM; return (NULL); } euidp=(PCLEUID *)realloc(p->pcl_euid, sizeof(PCLEUID)*(p->pcl_euidsize+1)); if (!euidp) return (NULL); p->pcl_euid=euidp; (void)memcpy(&p->pcl_euid[p->pcl_euidsize], euid, sizeof(PCLEUID)); p->pcl_euidsize++; return (p); } static PCLENT * pclent_euid_copy(dst, src) PCLENT *dst; const PCLENT *src; { dst->pcl_euid=(PCLEUID *)malloc(sizeof(PCLEUID)*(src->pcl_euidsize)); if (!dst->pcl_euid) return (NULL); (void)memcpy(dst->pcl_euid, src->pcl_euid, sizeof(PCLEUID)*(src->pcl_euidsize)); dst->pcl_euidsize=src->pcl_euidsize; return (dst); } static int pclent_euid_match(p, uid) const PCLENT *p; uid_t uid; { const PCLEUID *euid; int i; for (i=0; ipcl_euidsize; ++i) { euid=&p->pcl_euid[i]; switch (euid->pcl_type) { case PCLEUID_S: if (euid->pcl_luid==uid) return (1); break; case PCLEUID_L: if (euid->pcl_luid>=uid) return (1); break; case PCLEUID_R: if (uid<=euid->pcl_ruid) return (1); break; case PCLEUID_LR: if (euid->pcl_luid<=uid && uid<=euid->pcl_ruid) return (1); break; } } return (0); } static void pclent_euid_clear(p) PCLENT *p; { if (p->pcl_euid) free(p->pcl_euid); p->pcl_euid=NULL; p->pcl_euidsize=0; } PCLENT * pclent_addeuid(p, euid) PCLENT *p; PCLEUID *euid; { return (pclent_euid_add(p, euid)); } static void pclent_type_add(p, t) PCLENT *p; int t; { p->pcl_type|=t; } static void pclent_type_set(p, t) PCLENT *p; int t; { p->pcl_type=t; } static void pclent_type_copy(dst, src) PCLENT *dst; const PCLENT *src; { dst->pcl_type=src->pcl_type; } static int pclent_type_match(p, m) const PCLENT *p; mode_t m; { if (S_ISDIR(m) && (p->pcl_type & PCL_TD)) return (1); if (S_ISCHR(m) && (p->pcl_type & PCL_TC)) return (1); if (S_ISBLK(m) && (p->pcl_type & PCL_TL)) return (1); if (S_ISREG(m) && (p->pcl_type & PCL_TR)) return (1); if (S_ISLNK(m) && (p->pcl_type & PCL_TL)) return (1); if (S_ISFIFO(m) && (p->pcl_type & PCL_TF)) return (1); if (S_ISSOCK(m) && (p->pcl_type & PCL_TS)) return (1); return (0); } static void pclent_type_clear(p) PCLENT *p; { p->pcl_type=0x0; } void pclent_addtype(p, t) PCLENT *p; int t; { pclent_type_add(p, t); } void pclent_settype(p, t) PCLENT *p; int t; { pclent_type_set(p, t); } void pclent_clear(p) PCLENT *p; { pclent_name_clear(p); #if ENABLE_REGEX pclent_ename_clear(p); #endif pclent_egid_clear(p); pclent_euid_clear(p); pclent_type_clear(p); p->pcl_marks=0x0; p->pcl_opt=0x0; } PCLENT * pclent_init(void) { PCLENT *p; p=(PCLENT *)malloc(sizeof(PCLENT)); if (!p) return(NULL); p->pcl_name=NULL; p->pcl_namesize=0; #if ENABLE_REGEX p->pcl_pattern=NULL; p->pcl_ename=NULL; p->pcl_enamesize=0; #endif p->pcl_egid=NULL; p->pcl_egidsize=0; p->pcl_euid=NULL; p->pcl_euidsize=0; p->pcl_type=0x0; p->pcl_marks=0x0; p->pcl_opt=0x0; return (p); } void pclent_close(p) PCLENT *p; { pclent_clear(p); free(p); } static PCLENT * pclent_copy(dst, src) PCLENT *dst; const PCLENT *src; { if (!pclent_name_copy(dst, src)) return (NULL); #if ENABLE_REGEX if (!pclent_ename_copy(dst, src)) return (NULL); #endif if (!pclent_egid_copy(dst, src)) return (NULL); if (!pclent_euid_copy(dst, src)) return (NULL); pclent_type_copy(dst, src); dst->pcl_marks=src->pcl_marks; dst->pcl_opt=src->pcl_opt; return (dst); } static int pclent_match(pclent, name, stat) const PCLENT *pclent; const char *name; const struct stat *stat; { #if ENABLE_REGEX if (pclent->pcl_namesize>0 || pclent->pcl_enamesize>0) { if (pclent_name_match(pclent, name)==0) { if (pclent_ename_match(pclent, name)==0) return (0); } } #else if (pclent->pcl_namesize>0) { if (pclent_name_match(pclent, name)==0) return (0); } #endif if (pclent->pcl_egidsize>0) { if (pclent_egid_match(pclent, stat->st_gid)==0) return (0); } if (pclent->pcl_euidsize>0) { if (pclent_euid_match(pclent, stat->st_uid)==0) return (0); } if (pclent->pcl_type!=0x0) { if (pclent_type_match(pclent, stat->st_mode)==0) return (0); } return (1); } /* PCL */ PCL * pcl_init(void) { PCL *p; p=(PCL *)malloc(sizeof(PCL)); if (!p) return (NULL); p->pcl_entries=NULL; p->pcl_size=0; p->pcl_inh=0x0; return (p); } void pcl_close(p) PCL *p; { pcl_clear(p); free(p); } void pcl_clear(p) PCL *p; { int i; for (i=0; ipcl_size; ++i) pclent_clear(&p->pcl_entries[i]); if (p->pcl_entries) free(p->pcl_entries); p->pcl_entries=NULL; p->pcl_size=0; p->pcl_inh=0; } static PCL * pcl_copy(dst, src) PCL *dst; const PCL *src; { int i; dst->pcl_inh=src->pcl_inh; dst->pcl_size=src->pcl_size; dst->pcl_entries=(PCLENT *)malloc(sizeof(PCLENT)*(src->pcl_size)); if (!dst->pcl_entries) return (NULL); for (i=0; ipcl_size; ++i) { if (!pclent_copy(&dst->pcl_entries[i], &src->pcl_entries[i])) return (NULL); } return (dst); } const PCLENT * pcl_match(pcl, name, stat, inh) const PCL *pcl; const char *name; const struct stat *stat; int inh; { const PCLENT *ent; int i; for (i=0; ipcl_size; ++i) { ent=&pcl->pcl_entries[i]; if (inh && !PCL_ISSET(ent->pcl_marks, PCL_MINH)) continue; if (pclent_match(ent, name, stat)!=0) return (ent); } return (NULL); } PCL * pcl_add(pcl, ent) PCL *pcl; const PCLENT *ent; { PCLENT *tp; tp=(PCLENT *)realloc(pcl->pcl_entries, sizeof(PCLENT)*(pcl->pcl_size+1)); if (!tp) return (NULL); if (!pclent_copy(&tp[pcl->pcl_size], ent)) return (NULL); pcl->pcl_entries=tp; pcl->pcl_size++; return (pcl); } static PCL * pcl_merge(parent, child) const PCL *parent; PCL *child; { int i, j, inhsize; if (child->pcl_inh!=PCL_IPRE && child->pcl_inh!=PCL_IPOST) return (child); for (inhsize=i=0; ipcl_size; ++i) { if (PCL_ISSET(parent->pcl_entries[i].pcl_marks, PCL_MINH)) inhsize++; } child->pcl_entries=(PCLENT *)realloc(child->pcl_entries, sizeof(PCLENT)*(child->pcl_size+inhsize)); if (!child->pcl_entries) return (NULL); if (child->pcl_inh==PCL_IPRE) { (void)memmove(&child->pcl_entries[inhsize], child->pcl_entries, sizeof(PCLENT)*child->pcl_size); j=0; } else { j=child->pcl_size; } for (i=0; ipcl_size; ++i) { if (PCL_ISSET(parent->pcl_entries[i].pcl_marks, PCL_MINH)) if (!pclent_copy(&child->pcl_entries[j++], &parent->pcl_entries[i])) return (NULL); } child->pcl_size+=inhsize; return (child); } /* PCLT */ static FTENT * pclt_datacpy(p, data, size) FTENT *p; void *data; size_t size; { p->ft_data=data; p->ft_size=1; return (p); } static void pclt_datadel(p) FTENT *p; { pcl_close (p->ft_data); } PCLT * pclt_init(void) { PCLT *p; p=ft_init(&pclt_datadel, &pclt_datacpy); if (!p) return (NULL); return (p); } void pclt_close(p) PCLT *p; { ft_close(p); } PCL * pclt_add(pclt, path, pcl) PCLT *pclt; const char *path; const PCL *pcl; { FTENT *ent; ent=ft_add(pclt, path, pcl, 0); if (!ent) return (NULL); return (ent->ft_data); } static FTENT * pclt_findparent(ent) FTENT *ent; { while ((ent=ent->ft_parent)!=NULL) { if (ent->ft_data) break; } return (ent); } static int pclt_merge_do(ent) FTENT *ent; { FTENT *parent; int i; if (0ft_level && ent->ft_data) { parent=pclt_findparent(ent); if (!pcl_merge(parent->ft_data, ent->ft_data)) return (-1); } for (i=0; ift_chsize; ++i) { if (pclt_merge_do(&ent->ft_childs[i])!=0) return (-1); } return (0); } int pclt_merge(pclt) PCLT *pclt; { return (pclt_merge_do(pclt->ft_root)); } PCL * pclt_get(pclt, path, inh_r) const PCLT *pclt; const char *path; int *inh_r; { FTENT *ent, *parent; *inh_r=0; ent=ft_find(pclt, path, &parent); if (!ent) { ent=parent; *inh_r=1; } if (!ent->ft_data) { ent=pclt_findparent(ent); *inh_r=1; } return (ent->ft_data); }