int form_serval_instance_path(char *buf, size_t bufsiz, const char *path) { if (snprintf(buf, bufsiz, "%s/%s", serval_instancepath(), path) < bufsiz) return 1; WHYF("Cannot form pathname \"%s/%s\" -- buffer too small (%lu bytes)", serval_instancepath(), path, (unsigned long)bufsiz); return 0; }
int monitor_socket_name(struct sockaddr_un *name){ int len; #ifdef linux /* Use abstract namespace as Android has no writable FS which supports sockets. Abstract namespace is just plain better, anyway, as no dead files end up hanging around. */ name->sun_path[0] = '\0'; /* XXX: 104 comes from OSX sys/un.h - no #define (note Linux has UNIX_PATH_MAX and it's 108(!)) */ snprintf(&name->sun_path[1],104-2,"%s", confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME)); /* Doesn't include trailing nul */ len = 1+strlen(&name->sun_path[1]) + sizeof(name->sun_family); #else snprintf(name->sun_path,104-1,"%s/%s", serval_instancepath(), confValueGet("monitor.socket",DEFAULT_MONITOR_SOCKET_NAME)); /* Includes trailing nul */ len = 1+strlen(name->sun_path) + sizeof(name->sun_family); #endif return len; }
static void _open_log_file(_log_iterator *it) { assert(it->state == &state_file); if (_log_file != NO_FILE) { if (_log_file_path == NULL) _log_file_path = getenv("SERVALD_LOG_FILE"); if (_log_file_path == NULL && !cf_limbo) { strbuf sbfile = strbuf_local(_log_file_path_buf, sizeof _log_file_path_buf); strbuf_path_join(sbfile, serval_instancepath(), log_file_directory_path(), NULL); _compute_file_start_time(it); if (config.log.file.path[0]) { strbuf_path_join(sbfile, config.log.file.path, NULL); } else { struct tm tm; (void)localtime_r(&it->file_start_time, &tm); strbuf_append_strftime(sbfile, "/serval-%Y%m%d%H%M%S.log", &tm); } if (strbuf_overrun(sbfile)) { _log_file = NO_FILE; _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log file name - buffer overrun"); } else { _log_file_start_time = it->file_start_time; _log_file_path = strbuf_str(sbfile); } } if (!_log_file) { if (_log_file_path == NULL) { if (cf_limbo) return; _log_file = NO_FILE; _logs_printf_nl(serverMode ? LOG_LEVEL_WARN : LOG_LEVEL_INFO, __NOWHERE__, "No log file configured"); } else { // Create the new log file. size_t dirsiz = strlen(_log_file_path) + 1; char _dir[dirsiz]; strcpy(_dir, _log_file_path); const char *dir = dirname(_dir); // modifies _dir[] if (mkdirs(dir, 0700) != -1 && (_log_file = fopen(_log_file_path, "a"))) { setlinebuf(_log_file); memset(it->state, 0, sizeof *it->state); // The first line in every log file must be the starting time stamp. (After that, it is up // to _log_update() to insert other mandatory messages in any suitable order.) _log_current_datetime(it, LOG_LEVEL_INFO); _logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Logging to %s (fd %d)", _log_file_path, fileno(_log_file)); // Update the log symlink to point to the latest log file. strbuf sbsymlink = strbuf_alloca(400); strbuf_path_join(sbsymlink, serval_instancepath(), "serval.log", NULL); if (strbuf_overrun(sbsymlink)) _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot form log symlink name - buffer overrun"); else { const char *f = _log_file_path; const char *s = strbuf_str(sbsymlink); const char *relpath = f; for (; *f && *f == *s; ++f, ++s) if (*f == '/') relpath = f; while (*relpath == '/') ++relpath; while (*s == '/') ++s; if (strchr(s, '/')) relpath = _log_file_path; unlink(strbuf_str(sbsymlink)); if (symlink(relpath, strbuf_str(sbsymlink)) == -1) _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot symlink %s to %s - %s [errno=%d]", strbuf_str(sbsymlink), relpath, strerror(errno), errno); } // Expire old log files. size_t pathsiz = strlen(_log_file_path) + 1; char path[pathsiz]; while (1) { strcpy(path, _log_file_path); const char *base = basename(path); // modifies path[] DIR *d = opendir(dir); if (!d) { _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot expire log files: opendir(%s) - %s [errno=%d]", dir, strerror(errno), errno); break; } struct dirent oldest; memset(&oldest, 0, sizeof oldest); unsigned count = 0; while (1) { struct dirent ent; struct dirent *ep; int err = readdir_r(d, &ent, &ep); if (err) { _logs_printf_nl(LOG_LEVEL_ERROR, __HERE__, "Cannot expire log files: r_readdir(%s) - %s [errno=%d]", dir, strerror(err), err); break; } if (!ep) break; const char *e; if ( str_startswith(ent.d_name, "serval-", &e) && isdigit(e[0]) && isdigit(e[1]) && isdigit(e[2]) && isdigit(e[3]) // YYYY && isdigit(e[4]) && isdigit(e[5]) // MM && isdigit(e[6]) && isdigit(e[7]) // DD && isdigit(e[8]) && isdigit(e[9]) // HH && isdigit(e[10]) && isdigit(e[11]) // MM && isdigit(e[12]) && isdigit(e[13]) // SS && strcmp(&e[14], ".log") == 0 ) { ++count; if ( strcmp(ent.d_name, base) != 0 && (!oldest.d_name[0] || strcmp(ent.d_name, oldest.d_name) < 0) ) oldest = ent; } } closedir(d); if (count <= config.log.file.rotate || !oldest.d_name[0]) break; strbuf b = strbuf_local(path, pathsiz); strbuf_path_join(b, dir, oldest.d_name, NULL); assert(!strbuf_overrun(b)); _logs_printf_nl(LOG_LEVEL_INFO, __NOWHERE__, "Unlink %s", path); unlink(path); } } else { _log_file = NO_FILE; _logs_printf_nl(LOG_LEVEL_WARN, __HERE__, "Cannot create/append %s - %s [errno=%d]", _log_file_path, strerror(errno), errno); } } } } }
int create_serval_instance_dir() { return mkdirs(serval_instancepath(), 0700); }