/* areas_file routines for gtic */ #include #include #include #include #include #include "config.h" list_t *areas; struct flag_tab area_flag_tab[]={ {AREA_READONLY, "readonly"}, {AREA_PASSTHRU, "passthru"}, {AREA_NOANNOUNCE, "noannounce"}, {AREA_PRIVATE_ANNOUNCE, "private_announce"}, {AREA_NO_DESC, "no_desc"}, {AREA_NO_REPLACES, "no_replaces"}, {0, NULL} }; void read_areagroups_config(void) { FILE *fp; int linecnt=0,i; area_t *atmp; char buff[BUFSIZE],groupmask[SMALLBUFSIZE],dest[SMALLBUFSIZE],*p,*curgroup; if(areagroups_config==NULL) return; ass(areas!=NULL); fp=fopen(areagroups_config,"r"); if(fp==NULL) { e_printf("unable to open areagroups_config %s: ",areagroups_config); perror(""); abort2(); } while(1) { p=fgets(buff,sizeof(buff)-1,fp); linecnt++; if(p==NULL) break; if(buff[0]==0 || buff[0]=='#') continue; delcrlf(p); p=strtok(buff,":"); if(!p) { e_printf("%s(%d): invalid token #1",areagroups_config,linecnt); abort2(); } strcpy(groupmask,p); p=strtok(NULL,":"); if(!p) { e_printf("%s(%d): invalid token #2",areagroups_config,linecnt); abort2(); } strcpy(dest,p); p=strtok(NULL,":"); /* if(!p) { e_printf("%s(%d): invalid token #3",areagroups_config,linecnt); abort2(); }*/ for(i=0;igroup==NULL) curgroup="*"; else curgroup=atmp->group; if(wildmat_icase(curgroup,groupmask)) { if(!strcasecmp(dest,"options")) { if(atmp->group_options==FALSE) { if(p) atmp->flags|=parse_list_with_flag_tab(areagroups_config,linecnt,p, (struct flag_tab *)&area_flag_tab,", \t"); atmp->group_options=TRUE; } } /* TODO: another dest's support */ } } } fclose(fp); } void readareas(void) { FILE *fp; char buff1[BUFSIZE]; area_t *cur=NULL; char *p,*pp; int first=1; user_t *tmp; int linecnt=0; fp=fopen(areas_file,"r"); if(fp==NULL) { e_printf("unable to open areas_file %s: ",areas_file); perror(""); abort2(); } areas=list_init(); while(1) { p=fgets(buff1,sizeof(buff1)-1,fp); linecnt++; if(p) delcrlf(p); /* C has left-to-right order */ if(!p || (!strncasecmp(buff1,"area",4) && strchr(DELIM,buff1[4]))) { if(!p && !cur) break; if(!first) { if(!cur->path) { e_printf("%s(%d?): path for area %s not defined", areas_file,linecnt,cur->name?cur->name:"?not defined too?"); abort2(); } if(!cur->name) { e_printf("%s(%d?): name for area with path %s not defined", areas_file,linecnt,cur->path?cur->path:"?not defined too?"); abort2(); } if(!cur->users) { e_printf("%s(%d?): users for area %s with path %s not defined" ,areas_file,linecnt,cur->name?cur->name:"?not defined?", cur->path?cur->path:"?not defined?"); abort2(); } /*printf("DEBUG: readareas - name=%s, path=%s, desc=%s, newfiles=%s, &aka=%p," "*users=%p, flags=%04X\n",cur->name,cur->path,cur->desc,cur->newfile, cur->aka,cur->users,cur->flags); */ list_add(areas,cur->name,cur); if(!p) break; } else first=0; } if(buff1[0]==0 || buff1[0]=='#') continue; else if(!strncasecmp(buff1,"area",4) && strchr(DELIM,buff1[4])) { cur=xmalloc(sizeof(area_t)); /* default values */ cur->desc=NULL; cur->aka=NULL; cur->newfile=NULL; cur->group=NULL; cur->mode=-1; cur->flags=0; cur->real_flags=0; cur->group_options=FALSE; /* this keyword must be specifed */ cur->path=NULL; cur->name=NULL; cur->users=NULL; p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Area string",areas_file,linecnt); abort2(); } cur->name=xstrcpy(p); } else if(!strncasecmp(buff1,"description",11) && strchr(DELIM,buff1[11])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Description string",areas_file,linecnt); abort2(); } cur->desc=xstrcpy(p); } else if(!strncasecmp(buff1,"path",4) && strchr(DELIM,buff1[4])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Path string",areas_file,linecnt); abort2(); } cur->path=xstrcpy(p); } else if(!strncasecmp(buff1,"group",5) && strchr(DELIM,buff1[5])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Group string",areas_file,linecnt); abort2(); } cur->group=xstrcpy(p); } else if(!strncasecmp(buff1,"mode",4) && strchr(DELIM,buff1[4])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Mode string",areas_file,linecnt); abort2(); } sscanf(p,"%o",&(cur->mode)); } else if(!strncasecmp(buff1,"aka",3) && strchr(DELIM,buff1[3])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty AKA string",areas_file,linecnt); abort2(); } cur->aka=(node_t*)xmalloc(sizeof(node_t)); if(ftntonode(cur->aka,p,NULL)) { e_printf("%s(%d): \"%s\" is not a FTN addr",areas_file,linecnt,p); abort2(); } } else if(!strncasecmp(buff1,"links",5) && strchr(DELIM,buff1[5])) { p=strschr(buff1,DELIM); /* if(!p) { e_printf("%s(%d): empty Links string",areas_file,linecnt); abort2(); }*/ if(p==NULL) { cur->users=list_init(); continue; } p=strtok(p,", \t"); if(p) cur->users=list_init(); while(p) { pp=p[0]=='!'?p+1:p; tmp=list_find_entry(users,pp); if(!tmp) { e_printf("%s(%d): %s - unknown node",areas_file,linecnt,pp); abort2(); } /*printf("DEBUG: (areas.c) tmp->passwd=%s, flags=%d\n",tmp->passwd,tmp->flags); */ list_add(cur->users,p,tmp); p=strtok(NULL,", \t"); } } else if(!strncasecmp(buff1,"options",7) && strchr(DELIM,buff1[7])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Options string",areas_file,linecnt); abort2(); } cur->flags=parse_list_with_flag_tab(areas_file,linecnt,p, (struct flag_tab *)&area_flag_tab,", \t"); cur->real_flags=cur->flags; } else if(!strncasecmp(buff1,"newfile",7) && strchr(DELIM,buff1[7])) { p=strschr(buff1,DELIM); if(!p) { e_printf("%s(%d): empty Newfile string",areas_file,linecnt); abort2(); } cur->newfile=xstrcpy(p); } else { e_printf("%s(%d): %s - invalid keyword - ignored", areas_file,linecnt,buff1); } } read_areagroups_config(); } void writeareas(void) { int i,j; char new_path[PATH_MAX]; FILE *fp; struct stat stat_buff; area_t *a; int stat_fail=FALSE; ass(areas!=NULL); /* get uid,gid,mode for old areas_file */ if(stat(areas_file,&stat_buff)) { l_printf("Warning: unable to stat %s",areas_file); stat_fail=TRUE; } /* make a backup copy of areas_file */ strcpy(new_path,areas_file); strcat(new_path,".bak"); if(rename(areas_file,new_path)) l_printf("Warning: unable to move %s to %s",areas_file,new_path); /* try to create new areas_file, restore backup if fail */ fp=fopen(areas_file,"w"); if(fp==NULL) { e_printf("unable to create areas_file %s, trying to restore backup", areas_file); if(rename(new_path,areas_file)) e_printf("unable to restore areas file (%s to %s)",new_path,areas_file); return; } /* restore permissions and uid/gid */ fchmod(fileno(fp),stat_fail?0600:stat_buff.st_mode); if(stat_fail==FALSE) fchown(fileno(fp),stat_buff.st_uid,stat_buff.st_gid); /* write areas list */ for(i=0;iname!=NULL); ass(a->path!=NULL); ass(a->users!=NULL); fprintf(fp,"Area %s\n",a->name); if(a->desc) fprintf(fp,"Description %s\n",a->desc); fprintf(fp,"Path %s\n",a->path); if(a->aka) fprintf(fp,"AKA %s\n",nodetoftn(NULL,a->aka)); fprintf(fp,"Links"); for(j=0;jusers);j++) { fprintf(fp," %s",(char *)list_get_key(a->users,j)); } fprintf(fp,"\n"); if(a->group) fprintf(fp,"Group %s\n",a->group); if(a->real_flags) { fprintf(fp,"Options "); write_flag_tab_to_FILE(fp,a->real_flags,(struct flag_tab*)&area_flag_tab); fprintf(fp,"\n"); } if(a->mode!=-1) fprintf(fp,"Mode %o\n",a->mode); if(a->newfile) fprintf(fp,"Newfile %s\n",a->newfile); fprintf(fp,"\n"); } ass(fclose(fp)==0); }