Pull log naming code out of binary_log_writer and use in new logger

Flatbuffer logs will now be at /media/sda1/fbs_log-XYZ.

Change-Id: I7cfbc797cf8da415ff065387bf1867885c67c65d
diff --git a/aos/logging/log_namer.cc b/aos/logging/log_namer.cc
new file mode 100644
index 0000000..d4584ef
--- /dev/null
+++ b/aos/logging/log_namer.cc
@@ -0,0 +1,153 @@
+#include "aos/logging/log_namer.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <string>
+
+#include "aos/configuration.h"
+#include "glog/logging.h"
+
+namespace aos {
+namespace logging {
+namespace {
+void AllocateLogName(char **filename, const char *directory,
+                     const char *basename) {
+  int fileindex = 0;
+  DIR *const d = opendir(directory);
+  if (d == nullptr) {
+    PLOG(FATAL) << "could not open directory" << directory;
+  }
+  int index = 0;
+  while (true) {
+    errno = 0;
+    struct dirent *const dir = readdir(d);
+    if (dir == nullptr) {
+      if (errno == 0) {
+        break;
+      } else {
+        PLOG(FATAL) << "readdir(" << d << ") failed";
+      }
+    } else {
+      const std::string format_string = std::string(basename) + "-%d";
+      if (sscanf(dir->d_name, format_string.c_str(), &index) == 1) {
+        if (index >= fileindex) {
+          fileindex = index + 1;
+        }
+      }
+    }
+  }
+  closedir(d);
+
+  char previous[512];
+  ::std::string path = ::std::string(directory) + "/" + basename + "-current";
+  ssize_t len = ::readlink(path.c_str(), previous, sizeof(previous));
+  if (len != -1) {
+    previous[len] = '\0';
+  } else {
+    previous[0] = '\0';
+    LOG(INFO) << "Could not find " << path;
+  }
+  if (asprintf(filename, "%s/%s-%03d", directory, basename, fileindex) == -1) {
+    PLOG(FATAL) << "couldn't create final name";
+  }
+  LOG(INFO) << "Created log file (" << basename << "-" << fileindex
+            << ") in directory (" << directory
+            << "). Previous file "
+               "was ("
+            << previous << ").";
+}
+
+#ifdef AOS_ARCHITECTURE_arm_frc
+bool FoundThumbDrive(const char *path) {
+  FILE *mnt_fp = setmntent("/etc/mtab", "r");
+  if (mnt_fp == nullptr) {
+    LOG(FATAL) << "Could not open /etc/mtab";
+  }
+
+  bool found = false;
+  struct mntent mntbuf;
+  char buf[256];
+  while (!found) {
+    struct mntent *mount_list = getmntent_r(mnt_fp, &mntbuf, buf, sizeof(buf));
+    if (mount_list == nullptr) {
+      break;
+    }
+    if (strcmp(mount_list->mnt_dir, path) == 0) {
+      found = true;
+    }
+  }
+  endmntent(mnt_fp);
+  return found;
+}
+
+bool FindDevice(char *device, size_t device_size) {
+  char test_device[10];
+  for (char i = 'a'; i < 'z'; ++i) {
+    snprintf(test_device, sizeof(test_device), "/dev/sd%c", i);
+    LOG(INFO) << "Trying to access" << test_device;
+    if (access(test_device, F_OK) != -1) {
+      snprintf(device, device_size, "sd%c", i);
+      return true;
+    }
+  }
+  return false;
+}
+#endif
+}  // namespace
+
+std::string GetLogName(const char *basename) {
+#ifdef AOS_ARCHITECTURE_arm_frc
+  char folder[128];
+  {
+    char dev_name[8];
+    while (!FindDevice(dev_name, sizeof(dev_name))) {
+      LOG(INFO) <<  "Waiting for a device";
+      sleep(5);
+    }
+    snprintf(folder, sizeof(folder), "/media/%s1", dev_name);
+    while (!FoundThumbDrive(folder)) {
+      LOG(INFO) << "Waiting for" << folder;
+      sleep(1);
+    }
+    snprintf(folder, sizeof(folder), "/media/%s1/", dev_name);
+  }
+
+  if (access(folder, F_OK) == -1) {
+#else
+  const char *folder = configuration::GetLoggingDirectory();
+  if (access(folder, R_OK | W_OK) == -1) {
+#endif
+    LOG(FATAL) << "folder '" << folder << "' does not exist. please create it.";
+  }
+  LOG(INFO) << "logging to folder '" << folder << "'";
+
+  char *tmp;
+  AllocateLogName(&tmp, folder, basename);
+  char *tmp2;
+  if (asprintf(&tmp2, "%s/%s-current", folder, basename) == -1) {
+    PLOG(WARNING) << "couldn't create current symlink name";
+  } else {
+    if (unlink(tmp2) == -1 && (errno != EROFS && errno != ENOENT)) {
+      LOG(WARNING) << "unlink('" << tmp2 << "') failed";
+    }
+    if (symlink(tmp, tmp2) == -1) {
+      PLOG(WARNING) << "symlink('" << tmp << "', '" << tmp2 << "') failed";
+    }
+    free(tmp2);
+  }
+  std::string result = tmp;
+  free(tmp);
+  return result;
+}
+
+}  // namespace logging
+}  // namespace aos