int main(int argc, char **argv) { uchar aucParm[3] = {0x33,0x55,0xFF}; uchar ucCmd = CMD_NONE; PROT_WORK *worker; int iopt; TEST_BODY *test_body; while( (iopt=getopt(argc, argv, "dlusrhv")) != -1) { switch(iopt) { case 'd': g_ucdebug = 0x01; break; case 'l': ucCmd = CMD_LED; break; case 'u': ucCmd = CMD_USB; break; case 's': ucCmd = CMD_SD; break; case 'r': ucCmd = CMD_RTC; break; case 'h': print_usage(argv[0]); return; case 'v': print_ver(); return 0; default: break; } } if(CMD_NONE == ucCmd) { print_usage(argv[0]); return 0; } test_body = find_body((PROT_WORK *)&test_list, ucCmd); if(NULL != test_body) test_body(aucParm, 3); return 0; }
void print_usage(char *progname) { printf("Usage: %s [-d] [-f] [-h] [-v]\n", progname); printf(" -d: Enable debug output.\n"); printf(" -l: Test LED.\n"); printf(" -u: Test USB.\n"); printf(" -s: Test SD.\n"); printf(" -r: Test RTC.\n"); printf(" -h: Display This help information.\n"); printf(" -v: Get version information.\n"); print_ver(); return; }
/********************************************** * print_help() : output a short help message **********************************************/ void print_help( char *exe_path ) { printf("\n"); print_ver(); printf("USAGE:\n\t%s [OPTIONS] ACTION\n",exe_path); printf("OPTIONS\n"); printf("\t-h, --help display this help screen and exit\n"); printf("\t-v, --version display program version and exit\n"); printf("\t-c file, --config file use configuration file 'file'\n"); printf("\t-f, --forceload force loading SOCKS daemon even if\n"); printf("\t PID file exists\n"); printf("ACTIONS\n"); printf("\tstart start SOCKS daemon\n"); printf("\tshutdown shutdown SOCKS daemon\n"); printf("\n"); }
static void print_commands(int desc, char term, const struct cl_engine *engine) { unsigned i, n; const char *engine_ver = cl_retver(); const char *clamd_ver = get_version(); if (strcmp(engine_ver, clamd_ver)) { mdprintf(desc, "ENGINE VERSION MISMATCH: %s != %s. ERROR%c", engine_ver, clamd_ver, term); return; } print_ver(desc, '|', engine); mdprintf(desc, " COMMANDS:"); n = sizeof(commands)/sizeof(commands[0]); for (i=0;i<n;i++) { mdprintf(desc, " %s", commands[i].cmd); } mdprintf(desc, "%c", term); }
/* returns: * <0 for error * -1 out of memory * -2 other * 0 for async dispatched * 1 for command completed (connection can be closed) */ int execute_or_dispatch_command(client_conn_t *conn, enum commands cmd, const char *argument) { int desc = conn->sd; char term = conn->term; const struct cl_engine *engine = conn->engine; /* execute commands that can be executed quickly on the recvloop thread, * these must: * - not involve any operation that can block for a long time, such as disk * I/O * - send of atomic message is allowed. * Dispatch other commands */ if (conn->group) { switch (cmd) { case COMMAND_FILDES: case COMMAND_SCAN: case COMMAND_END: case COMMAND_INSTREAM: case COMMAND_INSTREAMSCAN: case COMMAND_VERSION: case COMMAND_PING: case COMMAND_STATS: case COMMAND_COMMANDS: /* These commands are accepted inside IDSESSION */ break; default: /* these commands are not recognized inside an IDSESSION */ conn_reply_error(conn, "Command invalid inside IDSESSION."); logg("$SESSION: command is not valid inside IDSESSION: %d\n", cmd); conn->group = NULL; return 1; } } switch (cmd) { case COMMAND_SHUTDOWN: pthread_mutex_lock(&exit_mutex); progexit = 1; pthread_mutex_unlock(&exit_mutex); return 1; case COMMAND_RELOAD: pthread_mutex_lock(&reload_mutex); reload = 1; pthread_mutex_unlock(&reload_mutex); mdprintf(desc, "RELOADING%c", term); /* we set reload flag, and we'll reload before closing the * connection */ return 1; case COMMAND_PING: if (conn->group) mdprintf(desc, "%u: PONG%c", conn->id, term); else mdprintf(desc, "PONG%c", term); return conn->group ? 0 : 1; case COMMAND_VERSION: { if (conn->group) mdprintf(desc, "%u: ", conn->id); print_ver(desc, conn->term, engine); return conn->group ? 0 : 1; } case COMMAND_COMMANDS: { if (conn->group) mdprintf(desc, "%u: ", conn->id); print_commands(desc, conn->term, engine); return conn->group ? 0 : 1; } case COMMAND_DETSTATSCLEAR: { detstats_clear(); return 1; } case COMMAND_DETSTATS: { detstats_print(desc, conn->term); return 1; } case COMMAND_INSTREAM: { int rc = cli_gentempfd(optget(conn->opts, "TemporaryDirectory")->strarg, &conn->filename, &conn->scanfd); if (rc != CL_SUCCESS) return rc; conn->quota = optget(conn->opts, "StreamMaxLength")->numarg; conn->mode = MODE_STREAM; return 0; } case COMMAND_STREAM: case COMMAND_MULTISCAN: case COMMAND_CONTSCAN: case COMMAND_STATS: case COMMAND_FILDES: case COMMAND_SCAN: case COMMAND_INSTREAMSCAN: return dispatch_command(conn, cmd, argument); case COMMAND_IDSESSION: conn->group = thrmgr_group_new(); if (!conn->group) return CL_EMEM; return 0; case COMMAND_END: if (!conn->group) { /* end without idsession? */ conn_reply_single(conn, NULL, "UNKNOWN COMMAND"); return 1; } /* need to close connection if we were last in group */ return 1; /*case COMMAND_UNKNOWN:*/ default: conn_reply_single(conn, NULL, "UNKNOWN COMMAND"); return 1; } }
/******************* * main() function *******************/ int main( int argc, char **argv ) { int force_load = FALSE; int sksize; char s[256]; struct sigaction sa; int res; int i; int act=-1; FILE *f; int allow; uint32_t adam; /* ** Parse command line parameters */ for( i=1; i<argc; i++ ) if( cmdln_arg_in(i,"-h","--help") ) { print_help(argv[0]); return 1; } else if( cmdln_arg_in(i,"-v","--version") ) { print_ver(); return 1; } else if( cmdln_arg_in(i,"-c","--config") ) strcpy(sz_cfgfile,argv[++i]); else if( cmdln_arg_in(i,"-f","--forceload") ) force_load = TRUE; else if( !strcmp(argv[i],"start") ) act = ACT_START; else if( !strcmp(argv[i],"shutdown") ) act = ACT_SHUTDOWN; else { fprintf(stderr,"Invalid argument: %s\n",argv[i]); return 2; } /* ** If mocks was run with no action parameter, output ** a short error message and exit. */ if( act<0 ) { fprintf(stderr,"Missing action\nSee %s -h for help\n",argv[0]); return 1; } /* ** Load and parse configuration file */ if( load_config() != ERR_NONE ) { fprintf(stderr,"Missing or bad configuration file.\n"); return 2; } /* ** Are we starting or shutting down? */ if( act==ACT_SHUTDOWN ) { printf("Shutting down "PROG_NAME" ... "); fflush(stdout); f = fopen(sz_pidfile,"r"); if( !f ) { printf("ERROR\n"); printf("\tPID file could not be opened "); printf("(maybe "PROG_NAME" is not running?)\n"); return 2; } if( fscanf(f,"%u",&res)<=0 ) { printf("ERROR\n"); printf("\tCould not read PID file\n"); return 2; } fclose(f); if( res<=0 ) { printf("ERROR\n"); printf("\tInvalid PID\n"); return 2; } if( kill(-res,SIGTERM)<0 ) { printf("ERROR\n"); printf("\tkill() failed\n"); return 2; } /* ** Give mocks some time to shut down cleanly and ** then kill it */ sleep(shutd_timeo); kill(-res,SIGKILL); printf("OK\n"); logstr(PROG_NAME" "PROG_VERSION" killed",NULL); return 0; } else { printf("Starting "PROG_NAME" ... "); fflush(stdout); } /* ** Check to see if a PID file already exists */ if( (f=fopen(sz_pidfile,"r"))!=NULL && !force_load ) { printf("\nAn instance of "PROG_NAME" might already be running.\n"); printf("Use %s -f to force execution\n",argv[0]); fclose(f); return 2; } /* ** Register signal handler for SIGCHILD and SIGTERM */ memset(&sa,0,sizeof(struct sigaction)); sa.sa_handler = handle_sig; sigaction(SIGTERM,&sa,0); sigaction(SIGCHLD,&sa,0); sigaction(SIGALRM,&sa,0); /* ** Start listening for client connections */ ad_socks.sa_family = AF_INET; *(ushort*)ad_socks.sa_data = htons(socks_port); res = open_serv_sock(&sk_socks,&ad_socks); if( res != ERR_NONE ) { printf("ERROR\n\t%s\n",sz_error[res]); return res; } /* ** SOCKS daemon successfully started */ printf("OK\n"); strcpy(s,PROG_NAME" "PROG_VERSION" started"); logstr(s,NULL); strcpy(s,"Listening on "); addr_to_ip(&ad_socks,s+strlen(s)); sprintf( s+strlen(s), ":%u", ntohs(((struct sockaddr_in*)&ad_socks)->sin_port) ); logstr(s,NULL); if( up_proxy ) { strcpy(s,"Relaying all traffic through "); sprintf( s+strlen(s),"%u.%u.%u.%u:%u", up_proxy->ip & 0xFF, (up_proxy->ip >> 8) & 0xFF, (up_proxy->ip >> 16) & 0xFF, up_proxy->ip >> 24, up_proxy->port ); logstr(s,NULL); } /* ** Now, remember we must act as a daemon, ** so let's fork() and detach. */ switch( fork() ) { case 0: setsid(); break; case -1: printf("ERROR\n\tfork() failed - cannot detach daemon\n"); exit(1); default: exit(0); } /* ** Create PID file */ f = fopen(sz_pidfile,"w"); if( !f ) logstr("WARNING: PID file could not be created!\n",NULL); else { fprintf(f,"%u",getpid()); fclose(f); } /* ** Entering the accept loop */ while( 1 ) { /* ** If we're already working with the maximum number of ** client connections, wake up every second to check ** if any connection closed and if not, ignore any other ** connection requests. */ if( con_cnt >= max_con_cnt ) { sleep(1); continue; } sksize = SOCK_SIZE; sk_client = accept( sk_socks,&ad_client,&sksize ); if( sk_client==-1 ) { if( errno!=EINTR ) logstr("Error: accept() failed",NULL); continue; } /* * Match the connection against our * client filter. */ allow = (filter_policy == FP_ALLOW); for( i=0; i<filter_except_cnt; i++ ) { memcpy(&adam,ad_client.sa_data+2,4); adam ^= filter_excepts[i]; adam &= htonl(0xFFFFFFFF << (32-filter_except_masks[i])); if( !adam ) { allow = !allow; break; } } if( !allow ) { logstr("Blocked by filter!",&ad_client); close(sk_client); continue; } switch( fork() ) { case 0: child = 1; close(sk_socks); logstr("Incoming connection",&ad_client); res = handle_con(); close(sk_client); exit(res); break; case -1: logstr("Could not accept connection (fork() error)",&ad_client); close(sk_client); break; default: if( ++con_cnt >= max_con_cnt ) { printf("Maximum daemon load reached: %d active connections", con_cnt); logstr(s,NULL); } close(sk_client); break; } /* end switch */ } /* end while */ close(sk_socks); return 0; }
/*=export_func optionVersionStderr * private: * * what: Print the program version to stderr * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * This routine will print the version to stderr. =*/ void optionVersionStderr(tOptions * pOpts, tOptDesc * pOD) { print_ver(pOpts, pOD, stderr); }
/*=export_func optionPrintVersion * private: * * what: Print the program version * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * This routine will print the version to stdout. =*/ void optionPrintVersion(tOptions * pOpts, tOptDesc * pOD) { print_ver(pOpts, pOD, stdout); }