#include #include #include #include #include #include #include #include #ifdef FreeBSD #include #define SU "/usr/bin/su" #define CP "/bin/cp" #define KILLALL "/usr/bin/killall" #define IPCS "/usr/bin/ipcs" #define IPCRM "/usr/bin/ipcrm" #define AWK "/usr/bin/awk" #endif #ifdef Linux #include #define SU "/bin/su" #define CP "/bin/cp" #define KILLALL "/usr/bin/killall" #endif int HaveBBSADM(void) { gid_t gids[NGROUPS_MAX]; int i, ngids; struct group *gr; ngids = getgroups(NGROUPS_MAX, gids); if( (gr = getgrnam("bbsadm")) == NULL ){ puts("group bbsadm not found"); return 0; } for( i = 0 ; i < ngids ; ++i ) if( gr->gr_gid == gids[i] ) break; if( i == ngids ){ puts("permission denied"); return 0; } return 1; } int startbbs(int argc, char **argv) { if( setuid(0) < 0 ){ perror("setuid(0)"); exit(1); } puts("starting mbbsd: 23"); system("/home/bbs/bin/mbbsd 23"); puts("starting mbbsd:3000"); system("/home/bbs/bin/mbbsd 3000"); puts("starting mbbsd:3001"); system("/home/bbs/bin/mbbsd 3001"); puts("starting mbbsd:3002"); system("/home/bbs/bin/mbbsd 3002"); puts("starting mbbsd:3003"); system("/home/bbs/bin/mbbsd 3003"); puts("starting mbbsd:3004"); system("/home/bbs/bin/mbbsd 3004"); puts("starting mbbsd:3005"); system("/home/bbs/bin/mbbsd 3005"); puts("starting mbbsd:3006"); system("/home/bbs/bin/mbbsd 3006"); puts("starting mbbsd:3007"); system("/home/bbs/bin/mbbsd 3007"); puts("starting mbbsd:3008"); system("/home/bbs/bin/mbbsd 3008"); puts("starting mbbsd:3009"); system("/home/bbs/bin/mbbsd 3009"); puts("starting mbbsd:3010"); system("/home/bbs/bin/mbbsd 3010"); return 0; } int stopbbs(int argc, char **argv) { DIR *dirp; struct dirent *de; FILE *fp; char buf[512], fn[512]; if( !(dirp = opendir("run")) ){ perror("open " BBSHOME "/run"); exit(0); } while( (de = readdir(dirp)) ){ if( strstr(de->d_name, "mbbsd") && strstr(de->d_name, "pid")){ sprintf(fn, BBSHOME "/run/%s", de->d_name); if( (fp = fopen(fn, "r")) != NULL ){ if( fgets(buf, sizeof(buf), fp) != NULL ){ printf("stopping listening-mbbsd at pid %5d\n", atoi(buf)); kill(atoi(buf), 9); } fclose(fp); unlink(fn); } } } closedir(dirp); return 0; } int STOP(int argc, char **argv) { DIR *dirp; struct dirent *de; FILE *fp; char buf[512]; if( !(dirp = opendir("/proc")) ){ perror("open /proc"); exit(0); } while( (de = readdir(dirp)) ){ if( de->d_type & DT_DIR ){ sprintf(buf, "/proc/%s/cmdline", de->d_name); if( (fp = fopen(buf, "r")) ){ if( fgets(buf, sizeof(buf), fp) != NULL ){ if( strstr(buf, "mbbsd") ){ kill(atoi(de->d_name), 1); printf("stopping mbbsd at pid %5d\n", atoi(de->d_name)); } } fclose(fp); } } } closedir(dirp); return 0; } int restartbbs(int argc, char **argv) { stopbbs(argc, argv); sleep(1); startbbs(argc, argv); return 0; } int bbsadm(int argc, char **argv) { if( setuid(0) < 0 ){ perror("setuid(0)"); return 1; } puts("permission granted"); execl(SU, "su", "bbsadm", NULL); return 0; } int bbstest(int argc, char **argv) { if( access("mbbsd", 0) < 0 ){ perror("./mbbsd"); return 1; } system(CP " -f mbbsd testmbbsd"); if( setuid(0) < 0 ){ perror("setuid(0)"); return 1; } if( setuid(9999) < 0 ){ perror("setuid(9999)"); return 1; } system(KILLALL " testmbbsd"); execl("./testmbbsd", "testmbbsd", "9000", NULL); perror("execl()"); return 0; } int Xipcrm(int argc, char **argv) { char buf[256], cmd[256]; FILE *fp; sprintf(buf, IPCS " | " AWK " '{print $1 $2}'"); if( !(fp = popen(buf, "r")) ){ perror(buf); return 1; } while( fgets(buf, sizeof(buf), fp) != NULL ){ if( buf[0] == 't' || buf[0] == 'm' || buf[0] == 's' ){ buf[strlen(buf) - 1] = 0; sprintf(cmd, IPCRM " -%c %s\n", buf[0], &buf[1]); system(cmd); } } pclose(fp); system(IPCS); return 0; } struct { int (*func)(int, char **); char *cmd, *descript; } cmds[] = { {startbbs, "start", "start mbbsd at port 23, 3000~3010"}, {stopbbs, "stop", "killall listening mbbsd"}, {restartbbs, "restart", "stop and then start"}, {bbsadm, "bbsadm", "switch to user: bbsadm"}, {bbstest, "test", "run ./mbbsd as bbsadm"}, {Xipcrm, "ipcrm", "ipcrm all msg, shm, sem"}, {STOP, "STOP", "killall ALL mbbsd"}, {NULL, NULL, NULL} }; int main(int argc, char **argv) { int i = 0; if( !HaveBBSADM() ) return 1; if( argc >= 2 ){ chdir(BBSHOME); for( i = 0 ; cmds[i].func != NULL ; ++i ) if( strcmp(cmds[i].cmd, argv[1]) == 0 ){ cmds[i].func(argc - 2, &argv[2]); break; } } if( argc == 1 || cmds[i].func == NULL ){ /* usage */ printf("usage: bbsctl [command] [options]\n"); printf("commands:\n"); for( i = 0 ; cmds[i].func != NULL ; ++i ) printf("\t%-15s%s\n", cmds[i].cmd, cmds[i].descript); } return 0; }