void feed_program4(FILE *fin) { int qF, qT; char act, cF, cT; char in[32]; cmd_t cmd; if(prog) free(prog); if(p_cache) free(p_cache); prog = calloc(256,sizeof(cmd_t)); p_cache = calloc(128,sizeof(void*)); prog_len = 0; prog_size = 256; /*(1) read em*/ while(!feof(fin) /*&& fscanf(fin,"%i,%c,%c,%c,%i",&qF,&cF,&cT,&act,&qT)==5*/) { fgets(in,32,fin); if(!strchr(in,',')) break; qF = ((in[0]-'0')*10) + (in[1]-'0'); cF = in[3]; cT = in[5]; if(cT == 's' || cT == 'S') act = 's', cT = cF; else if(cT == 'l' || cT == 'L') act = 'l', cT = cF; else if(cT == 'r' || cT == 'R') act = 'r', cT = cF; else if(cT == 'u' || cT == 'U') act = 'u', cT = cF; else act = 'u'; qT = ((in[7]-'0')*10) + (in[8]-'0'); cmd= cmd_build(qF,cF,act,qT,cT); if(debug) printf("%s --> %2i %c %c %c %2i | %08X | %2i %c %c %c %2i\n",in, qF, cF, cT, act, qT, cmd, cmd_qF(cmd), cmd_cF(cmd), cmd_cT(cmd), "urls"[cmd_act(cmd)>>16], cmd_qT(cmd) ); if(prog_len >= prog_size) prog_size+=256, prog = realloc(prog,prog_size*sizeof(cmd_t)); prog[prog_len++]=cmd; } /*(2) sort em*/ qsort(prog,prog_len,sizeof(cmd_t), cmd_cmp); /*(3) make cache*/ { int i; qF=300; for(i=0;i<prog_len;i++) if(cmd_qF(prog[i])!=qF) qF = cmd_qF(prog[i]), p_cache[qF] = &prog[i]; } }
/** * main - Main program * * Parses command line options and enters either daemon or client mode. * * In daemon mode, acquires multicast routing sockets, opens IPC socket * and goes in receive-execute command loop. * * In client mode, creates commands from command line and sends them to * the daemon. */ int main(int argc, const char *argv[]) { int i, num_opts, result = 0; int start_daemon = 0; int background = 1; uint8 buf[MX_CMDPKT_SZ]; const char *arg; unsigned int cmdnum = 0; struct cmd *cmdv[16]; /* init syslog */ openlog(__progname, LOG_PID, LOG_DAEMON); if (argc <= 1) return usage(); /* Parse command line options */ for (num_opts = 1; (num_opts = num_option_arguments(argv += num_opts));) { if (num_opts < 0) /* error */ return usage(); /* handle option */ arg = argv[0]; switch (arg[1]) { case 'a': /* add route */ if (num_opts < 5) return usage(); break; case 'r': /* remove route */ if (num_opts < 4) return usage(); break; case 'j': /* join */ case 'l': /* leave */ if (num_opts != 3) return usage(); break; case 'k': /* kill daemon */ if (num_opts != 1) return usage(); break; case 'h': /* help */ return usage(); case 'v': /* verbose */ fputs(version_info, stderr); log_stderr = LOG_DEBUG; continue; case 'd': /* daemon */ start_daemon = 1; continue; case 'n': /* run daemon in foreground, i.e., do not fork */ background = 0; continue; case 'f': if (num_opts != 2) return usage(); conf_file = argv[1]; continue; case 'D': do_debug_logging = 1; continue; default: /* unknown option */ return usage(); } /* Check and build command argument list. */ if (cmdnum >= ARRAY_ELEMENTS(cmdv)) { fprintf(stderr, "Too many command options\n"); return usage(); } cmdv[cmdnum] = cmd_build(arg[1], argv + 1, num_opts - 1); if (!cmdv[cmdnum]) { perror("Failed parsing command"); for (i = 0; i < cmdnum; i++) free(cmdv[i]); return 1; } cmdnum++; } if (start_daemon) { /* only daemon parent enters */ if (geteuid() != 0) { smclog(LOG_ERR, 0, "Need root privileges to start %s", __progname); return 1; } start_server(background); if (!background) return 0; } /* Client or daemon parent only, the daemon never reaches this point */ /* send commands */ if (cmdnum) { int retry_count = 30; openlog(argv[0], LOG_PID, LOG_USER); /* connect to daemon */ while (ipc_client_init()) { switch (errno) { case EACCES: smclog(LOG_ERR, EACCES, "Need root privileges to connect to daemon"); break; case ENOENT: case ECONNREFUSED: /* When starting daemon, give it 30 times a 1/10 second to get ready */ if (start_daemon && --retry_count) { usleep(100000); continue; } smclog(LOG_WARNING, errno, "Daemon not running"); result = 1; break; default: smclog(LOG_WARNING, errno, "Failed connecting to daemon"); result = 1; break; } } for (i = 0; !result && i < cmdnum; i++) { int slen, rlen; struct cmd *command = cmdv[i]; /* Send command */ slen = ipc_send(command, command->len); /* Wait here for reply */ rlen = ipc_receive(buf, sizeof(buf)); if (slen < 0 || rlen < 0) { smclog(LOG_WARNING, errno, "Communication with daemon failed"); result = 1; } if (rlen != 1 || *buf != '\0') { fprintf(stderr, "Daemon error: %s\n", buf); result = 1; } } for (i = 0; i < cmdnum; i++) free(cmdv[i]); } return result; }