int answait(link_t * ld, int event, char * buf, int sz, char ** msg) { char * ptr; char * str; int rc; int xerrno = (-1); do { if ((rc = link_gets(ld, buf, sz))<0) return rc; ptr = buf; str = next_token(&ptr, " \n\t"); if (str == NULL) continue; xerrno = strtol(str, NULL, 10); } while (xerrno != 0 && xerrno < 400 && xerrno != event); *msg = ptr; return xerrno; }
int main(int argc, char ** argv) { int c; int fd; int rc; int i; int fRun = 0; int fDaemon = 0; int fUpdate = 0; int fConvert = 0; int fSQL = 0; int fDumpGates = 0; accbase_t Accbase_temp; acc_t new_acc; acc_t_old old_acc; char ** row; res_coreinit(); openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); // DumpQuery = 1; /* A 1. Redefine service port u 2. Update access at start d 3. Run Daemon c 4. Run console */ while ((c = getopt(argc, argv, OPTS)) != -1) { switch (c) { case 'A': ForceService = strtol(optarg, NULL, 10); break; case '2': fSQL = 1; break; case 'v': // verbose - show queries DumpQuery = 1; break; case 'f': Config_path = optarg; break; case 'c': ld->fStdio = 1; fRun = 1; break; case 'd': fDaemon = 1; fRun = 1; break; case 'u': fUpdate = 1; break; case 'o': fConvert = 1; break; case 't': proc_title = optarg; break; case 'Q': QueryFilename = optarg; break; case 'g': fDumpGates = 1; break; case 'q': QuietMode = 1; break; case 'h': case '?': usage(0); default: usage(-1); } } // Load configuration if (QuietMode == 0) fprintf(stderr, "Loading base configuration ... "); rc = conf_load(Config_path); if (rc < 0) { fprintf(stderr, "FAILURE\n"); syslog(LOG_ERR, "FAILURE - Can't load configuration"); exit(-1); } if (QuietMode == 0) fprintf(stderr, "OK.\n"); if (fSQL) { if (QuietMode == 0) fprintf(stderr, "Loading SQL configuration ... "); rc = cfg_load(Config_path, &config); if (rc < 0) { fprintf(stderr, "ERROR (Fatal, see syslog).\n"); exit(-1); } if (QuietMode == 0) fprintf(stderr, "OK.\nLoading scripts ... "); rc = qlist_load(config.DBscripts); if (rc < 0) { fprintf(stderr, "ERROR (fatal)\n"); exit(-1); } if (QuietMode == 0) fprintf(stderr, "OK.\n"); } // if fSQL // Converting old account table if (fConvert != 0) { fprintf(stderr, "Converting database ... "); // Open old account file rc = acc_baseopen(&Accbase_temp, accbase_name_old); if (rc != SUCCESS) { fprintf(stderr, "FAILURE - Can't open old account table\n"); exit(-1); } // Open new account file rc = acc_baseopen(&Accbase, conf_accfile); if (rc != SUCCESS) { rc = open(conf_accfile, O_RDONLY | O_CREAT | O_EXCL, 0600); if (rc < 0) { fprintf(stderr, "FAILURE - Can't open/create new account table\n"); exit(-1); } close(rc); rc = acc_baseopen(&Accbase, conf_accfile); if (rc != SUCCESS) { fprintf(stderr, "FAILURE - Can't open created account table\n"); exit(-1); } } // Ensure, that new table is empty rc = acc_reccount(&Accbase); if (rc != 0) { fprintf(stderr, "FAILURE - New account table must be empty !\n"); exit(-1); } // Copy accounts data memset(&new_acc, 0, sizeof(new_acc)); for(i=0; 1; i++) { rc = acci_get_old(&Accbase_temp, i, &old_acc); if (rc == IO_ERROR) { fprintf(stderr, "FAILURE - I/O error on read, (%d accounts copied) !\n", i); exit(-1); } if (rc == NOT_FOUND) break; new_acc.tag = old_acc.tag; new_acc.accno = old_acc.accno; new_acc.balance = old_acc.balance; new_acc.start = old_acc.start; new_acc.stop = old_acc.stop; new_acc.tariff = old_acc.reserv[0]; rc = acc_add(&Accbase, &new_acc); if (rc == IO_ERROR) { fprintf(stderr, "FAILURE - I/O error on write, (%d accounts copied) !\n", i); exit(-1); } if (rc != i) { fprintf(stderr, "FAILURE - Accno sync error (%d accounts copied) !\n", i); exit(-1); } } acc_baseclose(&Accbase_temp); acc_baseclose(&Accbase); fprintf(stderr, "SUCCESS (%d accounts copied) !\n", i); exit(-1); } if (fDaemon != 0 && ld->fStdio != 0) { fprintf(stderr, "Can't daemonize in console mode\n"); fDaemon = 0; } // Load gates table (check file integrity) rc = reslinks_load(LOCK_SH); if (rc != SUCCESS) { syslog(LOG_ERR, "Can't load gates file"); exit (-1); } if (fDumpGates) { printf("SET client_encoding = 'KOI8';\n\n"); printf("TRUNCATE beegates;\n"); printf("COPY beegates (res_id, rid, acc_id, ident) FROM stdin;\n"); for (i=0; i < linktabsz; i++) { printf ("%d\t%d\t%d\t%s\n", linktab[i].res_id, linktab[i].user_id, linktab[i].accno, linktab[i].username); } printf("\\.\n"); rc = acc_baseopen(&Accbase, conf_accfile); if (rc < 0) { syslog(LOG_ERR, "Can't open account database"); exit (-1); } printf("TRUNCATE beeaccs;\n"); printf("COPY beeaccs (id, tag_deleted, tag_broken, tag_frozen, tag_off, tag_unlim, tag_payman, tag_log, " "balance, tariff_id, inetin_summ, inetout_summ, money_summ, tcredit " ") FROM stdin;\n"); c = acc_reccount(&Accbase); for (i=0; i < c; i++) { rc = acc_get(&Accbase, i, &new_acc); if (rc < 0 && rc > ACC_BROKEN) continue; printf ("%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%g\t%d\t%lld\t%lld\t%g\t%g\n", i, new_acc.tag & ATAG_DELETED ? "t":"f", new_acc.tag & ATAG_BROKEN ? "t":"f", new_acc.tag & ATAG_FROZEN ? "t":"f", new_acc.tag & ATAG_OFF ? "t":"f", new_acc.tag & ATAG_UNLIMIT ? "t":"f", new_acc.tag & ATAG_PAYMAN ? "t":"f", new_acc.tag & ATAG_LOG ? "t":"f", new_acc.balance, new_acc.tariff, new_acc.inet_summ_in, new_acc.inet_summ_out, new_acc.money_summ, new_acc.tcredit); } printf("\\.\n"); exit(0); } // Open database (to check & update if needed) rc = acc_baseopen(&Accbase, conf_accfile); if (rc < 0) { syslog(LOG_ERR, "Can't open account database"); exit (-1); } rc = log_baseopen(&Logbase, conf_logfile); if (rc < 0) { syslog(LOG_ERR, "Can't open log database"); exit (-1); } rc = tariffs_load(conf_tariffile); if (rc < 0) { syslog(LOG_ERR, "Can't open tariff database"); exit (-1); } if (fSQL) { fprintf(stderr, "SQL init ... "); // Initialize connection DBdata = db2_init(config.DBtype, config.DBhost, config.DBname); if (DBdata == NULL) { fprintf(stderr, "FAULT. db_init() fails.\n"); exit (-1); } // Open database rc = db2_open(DBdata, config.DBlogin, config.DBpass); if (rc < 0) { fprintf(stderr, "FAULT. db_open() fails.\n"); exit (-1); } fprintf(stderr, "OK.\n"); // Perform immediate query from file if (QueryFilename != NULL) { fd = open(QueryFilename, O_RDONLY, 0); if (fd >= 0) { c = 0; rc = ioctl(fd, FIONREAD, &c); if (rc >= 0 && c > 1) { QueryBuffer = (char*)calloc(1, c + 1); if (QueryBuffer != NULL) { rc = read(fd, QueryBuffer, c); if (rc == c) { if (DumpQuery) printf("%s", QueryBuffer); rc = db2_execute(DBdata, "%s", QueryBuffer); if (rc < 0) fprintf(stderr, "QUERY: SQL error\n"); else fprintf(stderr, "QUERY: done.\n"); } else fprintf(stderr, "QUERY: File read error\n"); free(QueryBuffer); QueryBuffer = NULL; } else fprintf(stderr, "QUERY: Memory allocation error\n"); } else fprintf(stderr, "QUERY: File size error\n"); close(fd); } else fprintf(stderr, "QUERY: File access error - %s\n", strerror(errno)); } // Perform test query row = db2_search(DBdata, 0, "SELECT count(*) FROM accs"); if (row == NULL) { fprintf(stderr, "Test fails.\n"); exit (-1); } else fprintf(stderr, "Test OK. (%s accounts).\n", *row); } // if fSQL // Update resources permissions if (fUpdate != 0) access_update(); // Close database acc_baseclose(&Accbase); log_baseclose(&Logbase); tariffs_free(); // Close database if (fSQL) { rc = db2_close(DBdata); if (rc < 0) { fprintf(stderr, "FATAL: db2_close() fails.\n\n"); exit (-1); } } // if fSQL // Start server if (fRun) { if (fDaemon) { rc = daemon(0, 0); if (rc != SUCCESS) { syslog(LOG_ERR, "Can't daemonize, closing"); exit(-1); } if (proc_title == NULL) setproctitle("(daemon)"); else setproctitle(proc_title); } if (setenv("HOME", "/root", 0) == (-1)) syslog(LOG_ERR, "setenv(): %m"); rc = link_wait(ld, ForceService < 0 ? conf_coreport : ForceService); if (rc != -1) { if (ld->fStdio == 0) setproctitle("(child)"); else { if (proc_title == NULL) setproctitle("(console)"); else setproctitle(proc_title); } cmd_out(RET_COMMENT, "Billing ver %d.%d.%d.%d", VER_VER, VER_SUBVER, VER_REV, VER_SUBREV); cmd_out(RET_COMMENT, "loading configuration ..."); conf_free(); rc = conf_load(Config_path); if (rc < 0) { cmd_out(ERR_IOERROR, "failure"); exit(-1); } cmd_out(RET_COMMENT, "loading gates ..."); // ReLoad linktable rc = reslinks_load(LOCK_SH); if (rc != SUCCESS) { cmd_out(ERR_IOERROR, "failure: %s", strerror(errno)); exit(-1); } // Open database cmd_out(RET_COMMENT, "opening accounts ..."); rc = acc_baseopen(&Accbase, conf_accfile); if (rc < 0) { syslog(LOG_ERR, "Can't reopen account database"); cmd_out(ERR_IOERROR, "failure: %s", strerror(errno)); exit(-1); } cmd_out(RET_COMMENT, "opening log ..."); rc = log_baseopen(&Logbase, conf_logfile); if (rc < 0) { syslog(LOG_ERR, "Can't reopen log database"); cmd_out(ERR_IOERROR, "failure: %s", strerror(errno)); exit(-1); } cmd_out(RET_COMMENT, "loading tariffs ..."); rc = tariffs_load(conf_tariffile); if (rc < 0) { syslog(LOG_ERR, "Can't reopen tariff database"); cmd_out(ERR_IOERROR, "failure"); exit(-1); } if (fSQL) { cmd_out(RET_COMMENT, "connecting SQL ..."); rc = db2_open(DBdata, config.DBlogin, config.DBpass); if (rc < 0) { syslog(LOG_ERR, "Can't reopen SQL connection"); cmd_out(ERR_IOERROR, "FAILURE"); exit(-1); } /* if (ld->fStdio) { row = dbex_search(DBdata, 0, "log_session"); if (row == NULL || row[0] == NULL) { cmd_out(ERR_SYSTEM, "Session open failure"); exit(-1); } SessionId = strtoll(row[0], NULL, 10); if (SessionId < 1) { cmd_out(ERR_SYSTEM, "Session open failure (invalid id returned)"); exit(-1); } cmd_out(RET_COMMENT, "Log session (id: %lld)", SessionId); SessionPerm = PERM_SUPERUSER; strlcpy(SessionLogin, "admin", sizeof(SessionLogin)); UserId = 1; cmd_out(RET_COMMENT, "Root autologin ..."); } */ } // if fSQL cmd_out(RET_SUCCESS, "Ready"); while(1) { rc = link_gets(ld, sbuf, sizeof(sbuf)); if (rc == LINK_DOWN) break; if (rc == SUCCESS) { rc = cmd_exec(sbuf, NULL); if (rc == LINK_DOWN || rc == CMD_EXIT) break; } } } } // Close SQL connection if (fSQL) db2_close(DBdata); acc_baseclose(&Accbase); log_baseclose(&Logbase); return 0; }