Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
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);
	}
      }
    }
  }
}
Ejemplo n.º 4
0
int create_serval_instance_dir() {
    return mkdirs(serval_instancepath(), 0700);
}