/*
areas_file routines for gtic
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#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;i<list_head_max(areas);i++)
{
atmp=list_get_entry(areas,i);
ass(atmp!=NULL);
if(atmp->group==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;i<list_head_max(areas);i++)
{
a=list_get_entry(areas,i);
ass(a!=NULL);
ass(a->name!=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;j<list_head_max(a->users);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);
}
syntax highlighted by Code2HTML, v. 0.9.1