static void test_msm_put(void) { CU_ASSERT_EQUAL(msm_put(IDS|DDPLUS, 1), 0); CU_ASSERT_EQUAL(msm_put(PPS, 1), LDM7_DUP); log_clear(); CU_ASSERT_EQUAL(msm_put(NEXRAD3, 1), LDM7_DUP); log_clear(); CU_ASSERT_EQUAL(msm_put(NEXRAD3, 2), 0); }
static void test_msm_removePid(void) { pid_t pid; CU_ASSERT_EQUAL(msm_removePid(5), LDM7_NOENT); log_clear(); CU_ASSERT_EQUAL(msm_removePid(1), 0); CU_ASSERT_EQUAL(msm_getPid(IDS, &pid), LDM7_NOENT); log_clear(); }
void test_mdl_createAndExecute() { int status; pqueue* pq = (pqueue*)1; char* const tcpAddr = "127.0.0.1"; const unsigned short tcpPort = 38800; char* const addr = "224.0.0.1"; const unsigned short port = 1; int (*int_func)() = (int(*)())1; void (*void_func)() = (void(*)())2; McastInfo mcastInfo; Mdl* mdl; mcastInfo.group.addr = addr; mcastInfo.group.port = port; mcastInfo.server.addr = tcpAddr; mcastInfo.server.port = tcpPort; /* Invalid product-queue argument */ mdl = mdl_new(NULL, &mcastInfo, void_func, NULL); log_log(LOG_INFO); OP_ASSERT_TRUE(mdl == NULL); log_clear(); /* Invalid multicast information argument */ mdl = mdl_new(pq, NULL, void_func, NULL); log_log(LOG_INFO); OP_ASSERT_TRUE(mdl == NULL); log_clear(); /* Invalid missed-product-function argument */ mdl = mdl_new(pq, &mcastInfo, NULL, NULL); log_log(LOG_INFO); OP_ASSERT_TRUE(mdl == NULL); log_clear(); /* Trivial execution */ vcmtpReceiver_new_ExpectAndReturn( NULL, tcpAddr, tcpPort, int_func, int_func, void_func, addr, port, NULL, 0, NULL, cmp_cstr, cmp_short, NULL, NULL, NULL, cmp_cstr, cmp_short, NULL); mdl = mdl_new(pq, &mcastInfo, void_func, NULL); log_log(LOG_INFO); OP_ASSERT_FALSE(mdl == NULL); vcmtpReceiver_execute_ExpectAndReturn(NULL, 0, NULL); status = mdl_start(mdl); log_log(LOG_INFO); OP_ASSERT_EQUAL_INT(LDM7_SHUTDOWN, status); vcmtpReceiver_free_ExpectAndReturn(NULL, NULL); mdl_free(mdl); log_log(LOG_INFO); OP_VERIFY(); }
int main(int argc, char *argv[]) { (void) argc; (void) argv; struct log *l; l = log_new("/tmp/log_test.txt", LOG_ALL); assert(l); log_clear(l); log_set_level(l, LOG_INFO); log_debug(l, "module-1", "debug message\n"); log_set_level(l, LOG_DEBUG); log_debug(l, "module-1", "debug message\n"); log_info(l, "module-2", "info message\n"); log_warning(l, NULL, "warning message\n"); log_error(l, "module-1","error message\n"); log_printf(l, LOG_WARNING, "module-3", "more warnings - "); log_append(l, "%s\n", "\"this string is appended\""); fprintf(stdout, "log_print():\n"); log_print(l, STDOUT_FILENO); log_delete(l); return 0; }
// ends static void on_log_exit(int signo) { log_flush(); log_clear(); redis_close(&redis); exit(0); }
static void MainL() { log_clear(PRIMARY_LOG_FILENAME); log_text(PRIMARY_LOG_FILENAME, "initializing"); logg("value is %d", 555); log_ctx(PRIMARY_LOG_FILENAME, "context test"); // Note that if our program does not run for at least five seconds // or so, the S60 auto launch mechanism will consider that an error, // and this may result in some error dialog popping up. We use // WaitWhile() to avoid that sort of thing where an intrusive error // report is not called for. Calling WaitWhile will hopefully also // ensure that the system is somewhat up and running even right after // boot, so that there are no problems with querying the installed // apps information or anything like that. WaitWhile(); RFs fs; User::LeaveIfError(fs.Connect()); CleanupClosePushL(fs); TBool magicFileExists = MagicFileExists(fs); if (!magicFileExists) { TBool isAppInstalled = IsAppInstalledL(); if (isAppInstalled) { MainLoopL(); } else { logt("program to launch not installed"); } } else { logt("magic file exists"); } CleanupStack::PopAndDestroy(); // fs }
/* * Opens the database environment. * * ARGUMENTS: * path Pathname of the database directory. Shall not be NULL. * The client can free it upon return. * dbEnv Pointer to a pointer to the database environment. Shall * not be NULL. "*dbEnv" is set upon successful return. * RETURNS: * 0 Success. "*dbEnv" is set. * ENOMEM System error. "log_start()" called. * EIO Backend database error. "log_start()" called. */ static RegStatus openEnvironment( const char* const path, DB_ENV** const dbEnv) { RegStatus status; DB_ENV* env; assert(NULL != path); log_clear(); if (0 == (status = createEnvHandle(path, &env))) { /* * The database is configured for "concurrent data store" * access rather than for transactional access because the * former is faster and sufficient. */ status = env->open(env, path, DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0); if (status) { log_add("Couldn't open environment for database \"%s\"", path); status = EIO; } else { *dbEnv = env; } if (status) (void)env->close(env, 0); } /* "env" allocated */ return status; }
/* * Closes the cursor. * * Arguments: * backend Pointer to the backend database. Shall not be NULL. * Returns: * 0 Success. * EIO Backend database error. "log_start()" called. */ static RegStatus closeCursor( Backend* const backend) { RegStatus status = 0; /* success */ Cursor* const cursor = &backend->cursor; DBC* const dbCursor = cursor->dbCursor; if (dbCursor) { log_clear(); if (status = dbCursor->close(dbCursor)) { log_add("Couldn't close cursor for database \"%s\"", getPath(backend->db)); status = EIO; } else { free(cursor->key.data); free(cursor->value.data); cursor->key.data = NULL; cursor->value.data = NULL; cursor->dbCursor = NULL; } } return status; }
/* * Prints to the standard output stream all values in the registry whose path * name starts with a given prefix. * * Arguments: * path Pointer to a registry pathname to be printed. Shall * not be NULL. * quiet Whether or not to be quiet about a pathname not * existing. * Returns: * 0 Success * NO_SUCH_ENTRY No such value or node. "log_flush()" called iff "quiet * == 0". * SYSTEM_ERROR Failure. "log_flush()" called. */ static Status printPath( const char* path, const int quiet) { Status status = 0; /* success */ RegStatus regStatus; char* value; log_debug("%s printing path \"%s\"", quiet ? "Quietly" : "Non-quietly", path); /* * The path name is first assumed to reference an existing value; * otherwise, the value wouldn't be printed. */ if (0 == (regStatus = reg_getString(path, &value))) { if (NULL != value) { (void)printf("%s\n", value); free(value); } /* "value" allocated */ } /* got value-string */ else { if (ENOENT != regStatus) { log_flush_error(); status = SYSTEM_ERROR; } else { /* * The path must reference a node. */ RegNode* node; log_clear(); if (0 != (regStatus = reg_getNode(path, &node, 0))) { if (ENOENT == regStatus) { if (!quiet) { log_error("No such value or node: \"%s\"", path); } status = NO_SUCH_ENTRY; } else { log_flush_error(); status = SYSTEM_ERROR; } } /* didn't get node */ else { _pathPrefix = path; if (0 != reg_visitNodes(node, printNodeValues)) { log_flush_error(); status = SYSTEM_ERROR; } /* error visiting nodes */ } /* got node */ } /* no such value */ } /* didn't get value-string */ return status; }
static void setup (void) { log_clear(); test_transport_recv_calls = 0; test_transport_send_calls = 0; g_instance = cometd_new(); cometd_configure(g_instance, COMETDOPT_URL, TEST_SERVER_URL); }
static void test_keyWithSpace(void) { RegStatus status; char* value; status = reg_putString("/foo key", "foo value 0"); CU_ASSERT_EQUAL(status, EINVAL); log_clear(); }
static void test_regMissing(void) { RegStatus status; char* value; /* The registry shouldn't exist. */ status = reg_getString("/foo_key", &value); CU_ASSERT_EQUAL(status, EIO); log_clear(); }
static void test_msm_getPid(void) { pid_t pid; CU_ASSERT_EQUAL(msm_getPid(NIMAGE, &pid), LDM7_NOENT); log_clear(); CU_ASSERT_EQUAL(msm_getPid(IDS, &pid), 0); CU_ASSERT_EQUAL(pid, 1); CU_ASSERT_EQUAL(msm_getPid(NEXRAD3, &pid), 0); CU_ASSERT_EQUAL(pid, 2); }
void test_vcmtpReceiver_new() { int status; VcmtpCReceiver* receiver; const char* addr = "224.0.0.1"; const unsigned short port = 1; status = vcmtpReceiver_new(NULL, bof_func, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = vcmtpReceiver_new(&receiver, NULL, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = vcmtpReceiver_new(&receiver, bof_func, NULL, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = vcmtpReceiver_new(&receiver, bof_func, eof_func, NULL, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = vcmtpReceiver_new(&receiver, bof_func, eof_func, missed_file_func, NULL, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = vcmtpReceiver_new(&receiver, bof_func, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(0, status); log_clear(); OP_VERIFY(); }
/* Fail a redirect. We have already released the connection. */ static int fail_redirect(struct connection *conn) { if (conn->poll) printf("Failed redirect not closed: %s\n", conn->url); else { --outstanding; if (verbose > 1) printf("Failed redirect %s (%d)\n", conn->url, outstanding); } log_clear(conn); return 0; }
/** * Called by `pthread_create()`. The thread is cancelled by * `sender_terminate()`. * * @param[in] arg Pointer to sender. * @retval &0 Success. Input end of sender's termination pipe(2) is closed. */ static void* sender_run( void* const arg) { Sender* const sender = (Sender*)arg; static int status; pthread_cleanup_push(freeLogging, NULL); const int servSock = sender->sock; struct pollfd fds; fds.fd = servSock; fds.events = POLLIN; for (;;) { status = poll(&fds, 1, -1); // `-1` => indefinite timeout int cancelState; (void)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancelState); if (0 > status) break; if (fds.revents & POLLHUP) { status = 0; break; } if (fds.revents & POLLIN) { status = servlet_run(servSock); if (status) { LOG_ADD0("servlet_run() failure"); break; } } (void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &cancelState); } // `poll()` loop /* Because the current thread is ending: */ (status && !done) ? log_log(LOG_ERR) : log_clear(); // don't care about errors if termination requested pthread_cleanup_pop(1); // calls `log_free()` udebug("sender_run(): Returning &%d", status); return &status; }
/** * Sets the first log-message for the current thread. */ void log_start( const char* const fmt, /**< The message format */ ...) /**< Arguments referenced by the format */ { va_list args; log_clear(); va_start(args, fmt); if (EAGAIN == log_vadd(fmt, args)) { va_end(args); va_start(args, fmt); (void)log_vadd(fmt, args); } va_end(args); }
void raft_clear(raft_server_t* me_) { raft_server_private_t* me = (raft_server_private_t*)me_; me->current_term = 0; me->voted_for = -1; me->timeout_elapsed = 0; me->voting_cfg_change_log_idx = -1; raft_set_state((raft_server_t*)me, RAFT_STATE_FOLLOWER); me->current_leader = NULL; me->commit_idx = 0; me->last_applied_idx = 0; me->num_nodes = 0; me->node = NULL; me->voting_cfg_change_log_idx = 0; log_clear(me->log); }
/** * Starts a receiver on the current thread. Called by `pthread_create()`. * * @param[in] arg Pointer to receiver object. * @retval &0 Success. */ static void* receiver_start( void* const arg) { Receiver* const receiver = (Receiver*)arg; static int status; status = down7_start(receiver->down7); CU_ASSERT_EQUAL(status, LDM7_SHUTDOWN); // setDoneCondition(); // Because at end of thread: done ? log_clear() : log_log(LOG_ERR); log_free(); return &status; }
/* * Creates a database environment handle * * ARGUMENTS: * path Pathname of the database directory. Shall not be NULL. * The client can free it upon return. * dbEnv Pointer to a pointer to the database environment. Shall * not be NULL. "*dbEnv" is set upon successful return. * RETURNS: * 0 Success. "*dbEnv" is set. * ENOMEM System error. "log_start()" called. * EIO Backend database error. "log_start()" called. */ static RegStatus createEnvHandle( const char* const path, DB_ENV** const dbEnv) { RegStatus status; DB_ENV* env; assert(NULL != path); log_clear(); if (status = db_env_create(&env, 0)) { log_serror("Couldn't create environment handle for database: %s", db_strerror(status)); status = ENOMEM; } else { env->set_errcall(env, logDbError); if (status = env->set_isalive(env, is_alive)) { log_add("Couldn't register \"is_alive()\" function for " "database \"%s\"", path); status = EIO; } else { static const unsigned threadCount = 256; if (status = env->set_thread_count(env, threadCount)) { log_add("Couldn't set thread count to %u for database \"%s\"", threadCount, path); status = EIO; } else { *dbEnv = env; } } if (status) (void)env->close(env, 0); } /* "env" allocated */ return status; }
/** * Logs the currently-accumulated log-messages of the current thread and resets * the message-list for the current thread. */ void log_log( const int level) /**< The level at which to log the messages. One of * LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, or * LOG_DEBUG; otherwise, the behavior is undefined. */ { List* list = getList(); if (NULL != list && NULL != list->last) { static const unsigned allPrioritiesMask = LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_NOTICE) | LOG_MASK(LOG_INFO) | LOG_MASK(LOG_DEBUG); const int priorityMask = LOG_MASK(level); lock(); if ((priorityMask & allPrioritiesMask) == 0) { uerror("log_log(): Invalid logging-level (%d)", level); } else if (getulogmask() & priorityMask) { const Message* msg; for (msg = list->first; NULL != msg; msg = msg->next) { /* * NB: The message is not printed using "ulog(level, * msg->string)" because "msg->string" might have formatting * characters in it (e.g., "%") from, for example, a call to * "s_prod_info()" with a dangerous product-identifier. */ ulog(level, "%s", msg->string); if (msg == list->last) break; } /* message loop */ } /* messages should be printed */ unlock(); log_clear(); } /* have messages */ }
/** * Creates a read/write lock based on creating a new semaphore set. Any previous * semaphore set will be deleted. * * @retval RWL_SUCCESS Success * @retval RWL_SYSTEM System error. See "errno". log_add() called. */ static srwl_Status createLock( const key_t key /**< [in] the key associated with the semaphore */, int* const semId /**< [out] pointer to the semaphore identifier */) { srwl_Status status; int id; (void) deleteSemSet(semget(key, 0, read_write)); log_clear(); id = semget(key, SI_NUM_SEMS, IPC_CREAT | IPC_EXCL | read_write); if (-1 == id) { LOG_SERROR0("Couldn't create semaphore set"); status = RWL_SYSTEM; } else { unsigned short semVal[SI_NUM_SEMS]; union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ } arg; semVal[SI_LOCK] = 1; semVal[SI_NUM_READERS] = 0; arg.array = semVal; if (semctl(id, 0, SETALL, arg) == -1) { LOG_SERROR1("Couldn't initialize semaphore set: semId=%d", id); (void) deleteSemSet(id); status = RWL_SYSTEM; } else { *semId = id; status = RWL_SUCCESS; } } return status; }
/** * Performs common exit actions for a task of a downstream LDM-7: * -# Logs outstanding error messages if the downstream LDM-7 wasn't shutdown; * -# Frees log-message resources of the current thread; * -# Sets the status of the first task to exit a downstream LDM-7; * -# Sets the task-exited flag of the downstream LDM-7; and * -# Signals the wait condition-variable. * * @param[in] arg Pointer to the downstream LDM-7. * @param[in] status Return status of the exiting task. */ static void taskExit( Down7* const down7, int const status) { /* * Finish with logging. */ done ? log_clear() : log_log(LOG_ERR); // because end of thread log_free(); /* * Inform the managing thread. */ lockWait(down7); if (down7->exitStatus < 0) down7->exitStatus = status; down7->taskExited = 1; pthread_cond_signal(&down7->waitCond); unlockWait(down7); }
/** * Forks the current process in the context of the LDM. Does whatever's * necessary before and after the fork to ensure correct behavior. Terminates * the child process if the fork() was successful but an error occurs. * * @retval -1 Failure. "log_add()" called. * @retval 0 Success. The calling process is the child. * @return PID of child process. The calling process is the parent. */ pid_t ldmfork(void) { pid_t pid; if (reg_close()) { pid = -1; } else { pid = fork(); if (0 == pid) { log_clear(); // So child process starts with no queued messages /* Child process */ } else if (-1 == pid) { /* System error */ log_syserr("Couldn't fork a child process"); } } return pid; }
void test_vcmtpReceiver_new() { int status; McastReceiver* receiver; const char* addr = "224.0.0.1"; const unsigned short port = 1; const char* const tcpAddr = "127.0.0.1"; const unsigned short tcpPort = 38800; status = mcastReceiver_new(NULL, tcpAddr, tcpPort, bof_func, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = mcastReceiver_new(&receiver, tcpAddr, tcpPort, NULL, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = mcastReceiver_new(&receiver, tcpAddr, tcpPort, bof_func, NULL, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = mcastReceiver_new(&receiver, tcpAddr, tcpPort, bof_func, eof_func, NULL, addr, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = mcastReceiver_new(&receiver, tcpAddr, tcpPort, bof_func, eof_func, missed_file_func, NULL, port, NULL); OP_ASSERT_EQUAL_INT(EINVAL, status); log_clear(); status = mcastReceiver_new(&receiver, tcpAddr, tcpPort, bof_func, eof_func, missed_file_func, addr, port, NULL); OP_ASSERT_EQUAL_INT(0, status); log_clear(); OP_VERIFY(); }
/* * Function: ParseDialTemplate() * * Parameters: parseptr - pointer to bytes to be parsed * * Description: Parse the contents of a dial template XML file * All Start and end tags are ignored * The empty element <TEMPLATE is parsed by ParseDialEntry * * Returns: false if parse fails else true */ boolean ParseDialTemplate (char *parseptr) { char buffer[MAX_TEMPLATE_LENGTH]; XMLToken tok; int LookKey; int LookEndKey; int errors = 0; int insideDialPlan = 0; LookKey = 0; LookEndKey = 0; FreeDialTemplates(); /* * reset the version stamp so that dialplans that do not contain versionStamp * tag will not keep the previous versionstamp. */ g_dp_version_stamp[0] = 0; if (parseptr == NULL) { debugif_printf("ParseDialTempate(): parseptr=NULL Returning.\n"); return (FALSE); } while ((tok = parse_xml_tokens(&parseptr, buffer, sizeof(buffer))) != TOK_EOF) { if (LookEndKey) { if (tok == TOK_RBRACKET) { LookEndKey = 0; } else if ((tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "DIALTEMPLATE")) { insideDialPlan = 0; } } else if (tok == TOK_LBRACKET) { LookKey = 1; } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "DIALTEMPLATE")) { insideDialPlan = 1; } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !strcmp(buffer, "TEMPLATE")) { if (insideDialPlan) { errors += ParseDialEntry(&parseptr); } else { errors++; } } else if ((LookKey != 0) && (tok == TOK_KEYWORD) && !cpr_strcasecmp(buffer, "versionStamp")) { if (insideDialPlan) { /* <versionStamp> tag found. parse it */ errors += ParseDialVersion(&parseptr); } else { errors++; } } else if (tok == TOK_ENDLBRACKET) { LookEndKey = 1; } else { LookKey = 0; } } /* * If we had any parse errors, put them into the log */ log_clear(LOG_CFG_PARSE_DIAL); if (errors != 0) { log_msg(LOG_CFG_PARSE_DIAL, errors, DialTemplateFile); return (FALSE); } return (TRUE); }
int main( int ac, char* av[]) { const char* pqfname = getQueuePath(); int status; int doSomething = 1; in_addr_t ldmIpAddr = (in_addr_t) htonl(INADDR_ANY ); unsigned ldmPort = LDM_PORT; ensureDumpable(); /* * deal with the command line, set options */ { extern int optind; extern int opterr; extern char *optarg; int ch; int logmask = LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_NOTICE); opterr = 1; while ((ch = getopt(ac, av, "I:vxl:nq:o:P:M:m:t:")) != EOF) { switch (ch) { case 'I': { in_addr_t ipAddr = inet_addr(optarg); if ((in_addr_t) -1 == ipAddr) { (void) fprintf(stderr, "Interface specification \"%s\" " "isn't an IP address\n", optarg); exit(1); } ldmIpAddr = ipAddr; break; } case 'v': logmask |= LOG_MASK(LOG_INFO); break; case 'x': logmask |= LOG_MASK(LOG_DEBUG); break; case 'l': logfname = optarg; break; case 'q': pqfname = optarg; setQueuePath(optarg); break; case 'o': toffset = atoi(optarg); if (toffset == 0 && *optarg != '0') { (void) fprintf(stderr, "%s: invalid offset %s\n", av[0], optarg); usage(av[0]); } break; case 'P': { unsigned port; int nbytes; if (sscanf(optarg, "%5u %n", &port, &nbytes) != 1 || 0 != optarg[nbytes] || port > 0xffff) { (void)fprintf(stderr, "%s: invalid port number: %s\n", av[0], optarg); usage(av[0]); } ldmPort = port; break; } case 'M': { int max = atoi(optarg); if (max < 0) { (void) fprintf(stderr, "%s: invalid maximum number of clients %s\n", av[0], optarg); usage(av[0]); } maxClients = max; break; } case 'm': max_latency = atoi(optarg); if (max_latency <= 0) { (void) fprintf(stderr, "%s: invalid max_latency %s\n", av[0], optarg); usage(av[0]); } break; case 'n': doSomething = 0; break; case 't': rpctimeo = (unsigned) atoi(optarg); if (rpctimeo == 0 || rpctimeo > 32767) { (void) fprintf(stderr, "%s: invalid timeout %s", av[0], optarg); usage(av[0]); } break; case '?': usage(av[0]); break; } /* "switch" statement */ } /* argument loop */ if (ac - optind == 1) setLdmdConfigPath(av[optind]); (void) setulogmask(logmask); if (toffset != TOFFSET_NONE && toffset > max_latency) { (void) fprintf(stderr, "%s: invalid toffset (%d) > max_latency (%d)\n", av[0], toffset, max_latency); usage(av[0]); } } /* command-line argument decoding */ if (logfname != NULL && *logfname == '-') { /* * Logging to standard error stream. Assume interactive. * * Make this process a process group leader so that all child processes * (e.g., upstream LDM, downstream LDM, pqact(1)s) will be signaled by * `cleanup()`. */ (void)setpgid(0, 0); // can't fail } #ifndef DONTFORK else { /* * Logging to system logging daemon or file. Make this process a daemon. */ pid_t pid; pid = ldmfork(); if (pid == -1) { log_add("Couldn't fork LDM daemon"); log_log(LOG_ERR); exit(2); } if (pid > 0) { /* parent */ (void) printf("%ld\n", (long) pid); exit(0); } /* detach the child from parents process group ?? */ (void) setsid(); // also makes this process a process group leader } #endif /* * Initialize logger. * (Close fd 2 to remap stderr to the logfile, when * appropriate. I know, this is anal.) */ if (logfname == NULL ) (void) fclose(stderr); else if (!(logfname[0] == '-' && logfname[1] == 0)) (void) close(2); (void) openulog(ubasename(av[0]), (LOG_CONS | LOG_PID), LOG_LDM, logfname); unotice("Starting Up (version: %s; built: %s %s)", PACKAGE_VERSION, __DATE__, __TIME__); /* * register exit handler */ if (atexit(cleanup) != 0) { serror("atexit"); unotice("Exiting"); exit(1); } /* * set up signal handlers */ set_sigactions(); /* * Close the standard input and standard output streams because they won't * be used (more anality :-) */ (void) fclose(stdout); (void) fclose(stdin); /* * Vet the configuration file. */ udebug("main(): Vetting configuration-file"); if (read_conf(getLdmdConfigPath(), 0, ldmIpAddr, ldmPort) != 0) { log_log(LOG_ERR); exit(1); } if (doSomething) { int sock = -1; if (lcf_isServerNeeded()) { /* * Create a service portal. This should be done before anything is * created because this is the function that relinquishes superuser * privileges. */ udebug("main(): Creating service portal"); if (create_ldm_tcp_svc(&sock, ldmIpAddr, ldmPort) != ENOERR) { /* error reports are emitted from create_ldm_tcp_svc() */ exit(1); } udebug("tcp sock: %d", sock); } /* * Verify that the product-queue can be open for writing. */ udebug("main(): Opening product-queue"); if ((status = pq_open(pqfname, PQ_DEFAULT, &pq))) { if (PQ_CORRUPT == status) { uerror("The product-queue \"%s\" is inconsistent", pqfname); } else { uerror("pq_open failed: %s: %s", pqfname, strerror(status)); } exit(1); } (void) pq_close(pq); pq = NULL; /* * Create the sharable database of upstream LDM metadata. */ udebug("main(): Creating shared upstream LDM database"); if ((status = uldb_delete(NULL))) { if (ULDB_EXIST == status) { log_clear(); } else { LOG_ADD0( "Couldn't delete existing shared upstream LDM database"); log_log(LOG_ERR); exit(1); } } if (uldb_create(NULL, maxClients * 1024)) { LOG_ADD0("Couldn't create shared upstream LDM database"); log_log(LOG_ERR); exit(1); } /* * Initialize the multicast sender map. */ #if WANT_MULTICAST if (msm_init()) { LOG_ADD0("Couldn't initialize multicast LDM sender map"); log_log(LOG_ERR); exit(1); } #endif /* * Re-read (and execute) the configuration file (downstream LDM-s are * started). */ lcf_free(); // Start with a clean slate to prevent duplicates udebug("main(): Reading configuration-file"); if (read_conf(getLdmdConfigPath(), 1, ldmIpAddr, ldmPort) != 0) { log_log(LOG_ERR); exit(1); } if (lcf_isServerNeeded()) { /* * Serve */ udebug("main(): Serving socket"); sock_svc(sock); } else { /* * Wait until all child processes have terminated. */ while (reap(-1, 0) > 0) /* empty */; } } // configuration-file will be executed return (0); }
/* * Called at exit. * This callback routine registered by atexit(). */ static void cleanup( void) { const char* const pqfname = getQueuePath(); unotice("Exiting"); lcf_savePreviousProdInfo(); free_remote_clss(); /* * Ensure release of COMINGSOON-reserved space in product-queue. */ clr_pip_5(); down6_destroy(); /* * Close product-queue. */ if (pq) { (void) pq_close(pq); pq = NULL; } /* * Ensure that this process has no entry in the upstream LDM database and * that the database is closed. */ (void) uldb_remove(getpid()); (void) uldb_close(); log_clear(); if (getpid() == getpgrp()) { /* * This process is the process group leader (i.e., the top-level * LDM server). */ if (portIsMapped) { int vers; /* * Superuser privileges might be required to unmap the * port on which the LDM is listening. */ rootpriv(); for (vers = MIN_LDM_VERSION; vers <= MAX_LDM_VERSION; vers++) { if (!pmap_unset(LDMPROG, vers)) uerror("pmap_unset(LDMPROG %lu, LDMVERS %lu) " "failed", LDMPROG, vers); else portIsMapped = 0; } unpriv(); } /* * Terminate all child processes. */ { /* * Ignore the signal I'm about to send my process group. */ struct sigaction sigact; (void) sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigact.sa_handler = SIG_IGN; (void) sigaction(SIGTERM, &sigact, NULL ); } /* * Signal my process group. */ unotice("Terminating process group"); (void) kill(0, SIGTERM); while (reap(-1, 0) > 0) ; /*empty*/ /* * Delete the upstream LDM database. */ (void) uldb_delete(NULL); #if WANT_MULTICAST /* * Destroy the multicast LDM sender map. */ msm_destroy(); #endif } /* * Free access-control-list resources. */ lcf_free(); /* * Close registry. */ if (reg_close()) log_log(LOG_ERR); /* * Terminate logging. */ (void) closeulog(); }
void log_free(log_t *log) { log_clear(log); }
int main(int argc, char *argv[]) { // stir depth and nonce length ub4 dep, sdep = MAXM, lnce = NLEN; ub4 rounds = 7; #ifdef MOTE-REPO enum CSPRNG rng = MOTE8; enum CSPRNG hasher = BB512; #else #ifdef BB-REPO enum CSPRNG rng = BB128; enum CSPRNG hasher = MOTE32; #else enum CSPRNG rng = MOTE32; enum CSPRNG hasher = BB512; #endif #endif enum ciphermode cmode = cmNone; enum ciphertype ctype = ctNone; enum outputform oform = ofASC; // input: message & key-phrase char msg[MAXM] = ""; char key[MAXM] = ""; // ciphertext & plaintext char ctx[MAXM], ptx[MAXM]; // derived & stretched key char kdf[MAXK] = ""; // IV/nonce char nce[MAXK] = ""; // check the command line if (argc >= 5) { if ((argc>=2) && strlen(argv[1])<MAXM) strcpy(msg,argv[1]); if ((argc>=3) && strlen(argv[1])<MAXK) strcpy(key,argv[2]); if (argc>=4) if ((strcmp(argv[3],"d")==0) || (strcmp(argv[3],"D")==0)) cmode = cmDecipher; else if ((strcmp(argv[3],"e")==0) || (strcmp(argv[3],"E")==0)) cmode = cmEncipher; else cmode = cmNone; if (argc>=5) #ifdef NEVER if ((strcmp(argv[4],"v")==0) || (strcmp(argv[4],"V")==0)) ctype = ctVernam; else #endif if ((strcmp(argv[4],"c")==0) || (strcmp(argv[4],"C")==0)) ctype = ctCaesar; else if ((strcmp(argv[4],"m")==0) || (strcmp(argv[4],"M")==0)) ctype = ctCaesarM; else ctype = ctNone; if (argc>=6) if ((strcmp(argv[5],"a")==0) || (strcmp(argv[5],"A")==0)) oform = ofASC; else oform = ofHEX; if (argc>=7) rng = (enum CSPRNG)(atoi(argv[6]) % 7); } // sanity checks if (TRUE) { if ((strlen(msg)<MINM) || (strlen(key)<MINK)) { info(); exit(0); } if ((cmode==cmNone) || (ctype==ctNone)) { info(); exit(0); } // only hex output available for Vernam if (ctype==ctVernam) oform=ofHEX; // output mode MOD 26? (not possible with Vernam) if ((oform==ofASC) && (ctype!=ctVernam)) { MOD=26; START='A'; } // no nonce scrambling or mixing available with hex output if (oform==ofHEX) SCRAMBLER=NONCE=MIX=FALSE; } // B E G I N P R E P A R A T I O N // preliminary seeding rSeedAll(key,rounds); if (SCRAMBLER) { sdep = SetDepth(rng,strlen(key)); #ifdef LOG char tmp[12]=""; sprintf(tmp,"%d",sdep); log_add("RNG",rName(rng)); log_add("HSH",rName(hasher)); log_add("DEP",tmp); #endif } if (NONCE) { // obtain nonce/IV hash of fixed or random length strcpy(nce,rNonce(hasher,FALSE)); // note nonce length for later lnce = strlen(nce); } // Key-derivation starts: if (TRUE) { // 1) seed MOTE with a key-derived hash strcpy(kdf,rHash(hasher,key,rStateSize(rng)*4)); rSeed(rng,kdf,rounds); // 2) calculate stir-depth dep = rDepth(rng,kdf); // 3) warm up MOTE with <dep> rounds rStir(rng,dep); } #ifdef TEST #ifdef LOG log_add("DKY",leftstr(kdf,LINE)); #endif #endif // Key-derivation ends. if (SCRAMBLER) { // prepare scrambler's random pool RandPool_Fill(rng); } // E N D P R E P A R A T I O N. // B E G I N M A I N C I P H E R S E Q U E N C E // Mode: Encipher if (cmode==cmEncipher) { // pre-process message if output is mod 26 if (oform==ofASC) strcpy(msg, PreProcessText(msg)); #ifdef LOG if (oform==ofASC) log_add("MSG",msg); #endif // Encrypt: Vernam XOR if (ctype==ctVernam) strcpy(ctx, Vernam(rng,msg)); // Encrypt: Caesar MOD if (ctype==ctCaesar) strcpy(ctx, rCaesarStr(rng, cmEncipher, msg, MOD, START)); // Encrypt: Caesar MIX if (ctype==ctCaesarM) strcpy(ctx, rmCaesarStr(rng, cmEncipher, msg, MOD, START)); // convert to hexadecimal as appropriate if (oform==ofHEX) strcpy(ctx,ascii2hex(ctx)); #ifdef LOG log_add(" CT",ctx); #endif if (MIX) { // Mix: Vigenere-cipher the ciphertext on the nonce strcpy(ctx,Vig(rng,cmode,ctx,nce,MOD,START,FALSE)); #ifdef LOG log_add("NCE",nce); log_add("VCT",ctx); #endif } if (NONCE) { // append ciphertext to nonce strcat(nce,ctx); strcpy(ctx,nce); #ifdef LOG log_add("NCT",ctx); #endif } if (SCRAMBLER) { // prepare scrambler context & scramble ciphertext InitRandPairs(rng,sdep,strlen(ctx)); strcpy(ctx,Scrambled(ctx,sdep)); #ifdef LOG log_add("SCT",ctx); #endif } } // Mode: Decipher if (cmode==cmDecipher) { // Convert hexadecimal ciphertext to ASCII (not in mod 26) if (oform==ofHEX) strcpy(ctx, hex2ascii(msg)); else strcpy(ctx, msg); if (SCRAMBLER) { #ifdef LOG log_add("SCT",ctx); #endif // prepare scrambler context & unscramble ciphertext InitRandPairs(rng,sdep,strlen(ctx)); strcpy(ctx,unScrambled(ctx,sdep)); #ifdef LOG log_add("UST",ctx); #endif } if (NONCE) { // detach ciphertext from nonce strcpy(nce,leftstr(ctx,lnce)); strcpy(ctx,rightstr(ctx,strlen(msg)-lnce)); #ifdef LOG log_add("VCT",ctx); log_add("NCE",nce); #endif } if (MIX) { // Un-mix: Vigenere-decipher the ciphertext on the nonce strcpy(ctx,Vig(rng,cmode,ctx,nce,MOD,START,FALSE)); #ifdef LOG log_add("UVC",ctx); #endif } // Decrypt: Vernam XOR if (ctype==ctVernam) strcpy(ptx, Vernam(rng,ctx)); // Decrypt: Caesar MOD if (ctype==ctCaesar) strcpy(ptx, rCaesarStr(rng, cmDecipher, ctx, MOD, START)); // Decrypt: Caesar MIX if (ctype==ctCaesarM) strcpy(ptx, rmCaesarStr(rng, cmDecipher,ctx, MOD, START)); // post-process plaintext if output is mod 26 if (oform==ofASC) strcpy(ptx, PostProcessText(ptx)); } // E N D M A I N C I P H E R S E Q U E N C E . #ifdef LOG log_show (); log_clear(); #endif // P R O G R A M O U T P U T if ((strcmp(ptx,"") != 0) || (strcmp(ctx,"") != 0)) { // Mode: Encipher if (cmode==cmEncipher) puts(ctx); // Mode: Decipher if (cmode==cmDecipher) puts(ptx); // belt'n'braces memory wipe if (TRUE) { rResetAll(); rResetAll(); memset(msg,0,sizeof(msg));memset(msg,0xFF,sizeof(msg));memset(msg,0,sizeof(msg)); memset(key,0,sizeof(key));memset(key,0xFF,sizeof(key));memset(key,0,sizeof(key)); memset(kdf,0,sizeof(kdf));memset(kdf,0xFF,sizeof(kdf));memset(kdf,0,sizeof(kdf)); memset(ctx,0,sizeof(ctx));memset(ctx,0xFF,sizeof(ctx));memset(ctx,0,sizeof(ctx)); memset(ptx,0,sizeof(ptx));memset(ptx,0xFF,sizeof(ptx));memset(ptx,0,sizeof(ctx)); dep=0; } } else info(); return 0; }