/* * sshchatd_config.c * * load/save the config information * * Author: Dario Rodriguez dario@softhome.net * This program is licensed under the terms of the GNU GPL v2.1+ */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/stat.h> #include <sys/types.h> #ifndef _BSD_SOURCE #define _BSD_SOURCE #endif #include <dirent.h> #include "sshchatd_config.h" #define USERSBLOCK 128 cconfig * cconfig_init(void) { cconfig *conf; DIR *dir; struct dirent *e; int pass,count,total; int nblocks; if((conf=malloc(sizeof(cconfig)))==NULL) return(NULL); memset(conf,0,sizeof(cconfig)); mkdir("users",0700); if((dir=opendir("users"))==NULL) { free(conf),conf=NULL; return(NULL); } for(pass=0,count=0;pass<=1;pass++,rewinddir(dir),total=count,count=0) { while((e=readdir(dir))!=NULL) { if(e->d_type!=DT_DIR) continue; if(!(e->d_name[0]>='a' && e->d_name[0]<='z') && !(e->d_name[0]>='A' && e->d_name[0]<='Z')) continue; /* usernames must start by a letter */ if(pass==0) { count++; } else if(count<total) { if((conf->users[conf->numusers]=strdup(e->d_name))==NULL) { cconfig_free(conf),conf=NULL; return(NULL); /* insuf. mem. */ } conf->numusers++; count++; } } if(pass==0) { nblocks=((count+USERSBLOCK-1))/USERSBLOCK; if(count>0 && (conf->users=malloc(sizeof(char *)*USERSBLOCK*nblocks))==NULL) { closedir(dir),dir=NULL; cconfig_free(conf),conf=NULL; return(NULL); /* No users or insuf. mem. */ } memset(conf->users,0,sizeof(char *)*USERSBLOCK*nblocks); conf->sizeusers=USERSBLOCK*nblocks; } } return(conf); } void cconfig_free(cconfig *conf) { int i; if(conf==NULL) return; if(conf->users!=NULL) { for(i=0;i<conf->numusers;i++) { if(conf->users[i]!=NULL) free(conf->users[i]),conf->users[i]=NULL; } conf->numusers=0; conf->sizeusers=0; free(conf->users),conf->users=NULL; } free(conf),conf=NULL; }