switched from fitpc/atom to prime/linux

Also removed a few old things that had nothing reasonable to be changed
to.
diff --git a/aos/linux_code/output/HTTPServer.cpp b/aos/linux_code/output/HTTPServer.cpp
new file mode 100644
index 0000000..1703d39
--- /dev/null
+++ b/aos/linux_code/output/HTTPServer.cpp
@@ -0,0 +1,153 @@
+#include "aos/linux_code/output/HTTPServer.h"
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <memory>
+
+#include "event2/event.h"
+
+#include "aos/common/scoped_fd.h"
+#include "aos/common/unique_malloc_ptr.h"
+
+namespace aos {
+namespace http {
+
+HTTPServer::HTTPServer(const char *directory, uint16_t port) :
+    directory_(directory), base_(event_base_new()), http_(evhttp_new(base_)) {
+  if (base_ == NULL) {
+    LOG(FATAL, "couldn't create an event_base\n");
+  }
+  if (http_ == NULL) {
+    LOG(FATAL, "couldn't create an evhttp\n");
+  }
+  if (evhttp_bind_socket(http_, "0.0.0.0", port) != 0) {
+    LOG(FATAL, "evhttp_bind_socket(%p, \"0.0.0.0\", %" PRIu16 ") failed\n",
+        http_, port);
+  }
+  evhttp_set_gencb(http_, StaticServeFile, this);
+}
+
+void HTTPServer::AddPage(const std::string &path,
+                         void (*handler)(evhttp_request *, void *), void *data) {
+  switch (evhttp_set_cb(http_, path.c_str(), handler, data)) {
+    case 0:
+      LOG(DEBUG, "set callback handler for '%s'\n", path.c_str());
+      break;
+    case -1:
+      LOG(INFO, "changed callback handler for '%s'\n", path.c_str());
+      break;
+    default:
+      LOG(WARNING, "evhttp_set_cb(%p, %s, %p, %p) failed\n", http_, path.c_str(),
+          handler, data);
+      break;
+  }
+}
+
+void HTTPServer::AddStandardHeaders(evhttp_request *request) {
+  if (evhttp_add_header(evhttp_request_get_output_headers(request),
+                        "Server", "aos::HTTPServer/0.0") == -1) {
+    LOG(WARNING, "adding Server header failed\n");
+  }
+}
+
+namespace {
+// All of these functions return false, NULL, or -1 if they fail (and send back
+// an error).
+
+// Returns the path of the file that is being requested.
+const char *GetPath(evhttp_request *request) {
+  // Docs are unclear whether this needs freeing, but it looks like it just
+  // returns an internal field of the request.
+  // Running valgrind with no freeing of uri or path doesn't report anything
+  // related to this code.
+  const evhttp_uri *uri = evhttp_request_get_evhttp_uri(request);
+  const char *path = evhttp_uri_get_path(uri);
+  if (path == NULL) {
+    evhttp_send_error(request, HTTP_BADREQUEST, "need a path");
+    return NULL;
+  }
+  if (strstr(path, "..") != NULL) {
+    evhttp_send_error(request, HTTP_NOTFOUND, "no .. allowed!!");
+    return NULL;
+  }
+  return path;
+}
+// Returns an fd open for reading for the file at "directory/path".
+int OpenFile(evhttp_request *request, const char *path,
+                   const char *directory) {
+  char *temp;
+  if (asprintf(&temp, "%s/%s", directory, path) == -1) {
+    LOG(WARNING, "asprintf(%p, \"%%s/%%s\", %p, %p) failed with %d: %s\n",
+        &temp, directory, path, errno, strerror(errno));
+    evhttp_send_error(request, HTTP_INTERNAL, NULL);
+    return -1;
+  }
+  const unique_c_ptr<char> filename(temp);
+  ScopedFD file(open(filename.get(), O_RDONLY));
+  if (!file) {
+    if (errno == ENOENT) {
+      evhttp_send_error(request, HTTP_NOTFOUND, NULL);
+      return -1;
+    }
+    LOG(ERROR, "open('%s', 0) failed with %d: %s\n", filename.get(),
+        errno, strerror(errno));
+    evhttp_send_error(request, HTTP_INTERNAL, NULL);
+    return -1;
+  }
+  return file.release();
+}
+// Returns the size of the file specified by the given fd.
+off_t GetSize(int file) {
+  struct stat info;
+  if (fstat(file, &info) == -1) {
+    LOG(ERROR, "stat(%d, %p) failed with %d: %s\n", file, &info,
+        errno, strerror(errno));
+    return -1;
+  }
+  return info.st_size;
+}
+bool SendFileResponse(evhttp_request *request, int file_num) {
+  ScopedFD file(file_num);
+  const off_t size = GetSize(file.get());
+  if (size == -1) {
+    evhttp_send_error(request, HTTP_INTERNAL, NULL);
+    return false;
+  }
+  evbuffer *const buf = evhttp_request_get_output_buffer(request);
+  if (evbuffer_add_file(buf, file.get(), 0, size) == -1) {
+    LOG(WARNING, "evbuffer_add_file(%p, %d, 0, %jd) failed\n", buf,
+        file.get(), static_cast<intmax_t>(size));
+    evhttp_send_error(request, HTTP_INTERNAL, NULL);
+    return false;
+  } else {
+    // it succeeded, so evhttp takes ownership
+    file.release();
+  }
+  evhttp_send_reply(request, HTTP_OK, NULL, NULL);
+  return true;
+}
+
+}  // namespace
+void HTTPServer::ServeFile(evhttp_request *request) {
+  AddStandardHeaders(request);
+
+  const char *path = GetPath(request);
+  if (path == NULL) return;
+
+  ScopedFD file(OpenFile(request, path, directory_));
+  if (!file) return;
+
+  if (!SendFileResponse(request, file.release())) return;
+}
+
+void HTTPServer::Run() {
+  event_base_dispatch(base_);
+  LOG(FATAL, "event_base_dispatch returned\n");
+}
+
+}  // namespace http
+}  // namespace aos
diff --git a/aos/linux_code/output/HTTPServer.h b/aos/linux_code/output/HTTPServer.h
new file mode 100644
index 0000000..99eb295
--- /dev/null
+++ b/aos/linux_code/output/HTTPServer.h
@@ -0,0 +1,58 @@
+#include "event2/buffer.h"
+#include "event2/http.h"
+
+#include <string>
+
+namespace aos {
+namespace http {
+
+// An HTTP server that serves files from a directory using libevent.
+// Also allows configuring certain URLs to be dynamically generated.
+class HTTPServer {
+ public:
+  HTTPServer(const char *directory, uint16_t port);
+  // Starts serving pages.
+  // Might not clean up everything before returning.
+  void Run();
+ protected:
+  template<class T> class MemberHandler {
+   public:
+    typedef void (T::*Handler)(evhttp_request *);
+    struct Holder {
+      T *self;
+      Handler handler;
+    };
+    static void Call(evhttp_request *request, void *handler_in) {
+      const Holder *const holder = static_cast<Holder *>(handler_in);
+      AddStandardHeaders(request);
+      ((holder->self)->*(holder->handler))(request);
+    }
+  };
+  void AddPage(const std::string &path, void (*handler)(evhttp_request *, void *),
+               void *data);
+  template<class T> void AddPage(const std::string &path,
+                                 typename MemberHandler<T>::Handler handler,
+                                 T *self) {
+    // have to put "typename" in, so the typedef makes it clearer
+    typedef typename MemberHandler<T>::Holder HolderType;
+    AddPage(path, MemberHandler<T>::Call, new HolderType{self, handler});
+  }
+  // This gets set up as the generic handler.
+  // It can also be called separately to serve the file that the request is
+  // requesting from the filesystem.
+  void ServeFile(evhttp_request *request);
+ private:
+  // The directory where files to be served come from.
+  const char *directory_;
+  // The main libevent structure.
+  event_base *const base_;
+  // The libevent HTTP server handle.
+  evhttp *const http_;
+  static void AddStandardHeaders(evhttp_request *request);
+  static void StaticServeFile(evhttp_request *request, void *self) {
+    static_cast<HTTPServer *>(self)->ServeFile(request);
+  }
+};
+
+}  // namespace http
+}  // namespace aos
diff --git a/aos/linux_code/output/ctemplate_cache.cc b/aos/linux_code/output/ctemplate_cache.cc
new file mode 100644
index 0000000..cf961c6
--- /dev/null
+++ b/aos/linux_code/output/ctemplate_cache.cc
@@ -0,0 +1,24 @@
+#include "aos/linux_code/output/ctemplate_cache.h"
+
+#include "aos/linux_code/configuration.h"
+#include "aos/common/once.h"
+
+namespace aos {
+namespace http {
+
+namespace {
+ctemplate::TemplateCache *CreateTemplateCache() {
+  ctemplate::TemplateCache *r = new ctemplate::TemplateCache();
+
+  r->SetTemplateRootDirectory(configuration::GetRootDirectory());
+
+  return r;
+}
+}  // namespace
+ctemplate::TemplateCache *get_template_cache() {
+  static Once<ctemplate::TemplateCache> once(CreateTemplateCache);
+  return once.Get();
+}
+
+}  // namespace http
+}  // namespace aos
diff --git a/aos/linux_code/output/ctemplate_cache.h b/aos/linux_code/output/ctemplate_cache.h
new file mode 100644
index 0000000..7e5dc3d
--- /dev/null
+++ b/aos/linux_code/output/ctemplate_cache.h
@@ -0,0 +1,12 @@
+#include "ctemplate/template_cache.h"
+
+namespace aos {
+namespace http {
+
+// Retrieves the cache used by all of the aos functions etc.
+// This cache will have its root directory set to the directory where the
+// executable is running from.
+ctemplate::TemplateCache *get_template_cache();
+
+}  // namespace http
+}  // namespace aos
diff --git a/aos/linux_code/output/evhttp_ctemplate_emitter.cc b/aos/linux_code/output/evhttp_ctemplate_emitter.cc
new file mode 100644
index 0000000..2301ffb
--- /dev/null
+++ b/aos/linux_code/output/evhttp_ctemplate_emitter.cc
@@ -0,0 +1,18 @@
+#include "aos/linux_code/output/evhttp_ctemplate_emitter.h"
+
+#include "aos/common/logging/logging.h"
+
+namespace aos {
+namespace http {
+
+void EvhttpCtemplateEmitter::Emit(const char *s, size_t slen) {
+  if (error_) return;
+  if (evbuffer_add(buf_, s, slen) != 0) {
+    LOG(ERROR, "evbuffer_add(%p, %p, %zd) failed\n",
+        buf_, s, slen);
+    error_ = true;
+  }
+}
+
+}  // namespace http
+}  // namespace aos
diff --git a/aos/linux_code/output/evhttp_ctemplate_emitter.h b/aos/linux_code/output/evhttp_ctemplate_emitter.h
new file mode 100644
index 0000000..5b8e96a
--- /dev/null
+++ b/aos/linux_code/output/evhttp_ctemplate_emitter.h
@@ -0,0 +1,34 @@
+#ifndef AOS_LINUX_CODE_OUTPUT_EVHTTP_CTEMPLATE_EMITTER_H_
+#define AOS_LINUX_CODE_OUTPUT_EVHTTP_CTEMPLATE_EMITTER_H_
+
+#include <string.h>
+
+#include "event2/buffer.h"
+#include "ctemplate/template_emitter.h"
+
+namespace aos {
+namespace http {
+
+// Writes everything directly into an evbuffer*.
+// Handles errors by refusing to write anything else into the buffer and storing
+// the state (which can be retrieved with error()).
+class EvhttpCtemplateEmitter : public ctemplate::ExpandEmitter {
+ public:
+  EvhttpCtemplateEmitter(evbuffer *buf) : buf_(buf), error_(false) {}
+  virtual void Emit(char c) { Emit(&c, 1); };
+  virtual void Emit(const std::string& s) { Emit(s.data(), s.size()); };
+  virtual void Emit(const char* s) { Emit(s, strlen(s)); }
+  virtual void Emit(const char* s, size_t slen);
+  // Retrieves whether or not there has been an error. If true, the error will
+  // already have been logged.
+  bool error() { return error_; }
+
+ private:
+  evbuffer *const buf_;
+  bool error_;
+};
+
+}  // namespace http
+}  // namespace aos
+
+#endif  // AOS_LINUX_CODE_OUTPUT_EVHTTP_CTEMPLATE_EMITTER_H_
diff --git a/aos/linux_code/output/output.gyp b/aos/linux_code/output/output.gyp
new file mode 100644
index 0000000..f697630
--- /dev/null
+++ b/aos/linux_code/output/output.gyp
@@ -0,0 +1,24 @@
+{
+  'targets': [
+    {
+      'target_name': 'http_server',
+      'type': 'static_library',
+      'sources': [
+        'HTTPServer.cpp',
+        'evhttp_ctemplate_emitter.cc',
+        'ctemplate_cache.cc',
+      ],
+      'dependencies': [
+        '<(EXTERNALS):libevent',
+        '<(EXTERNALS):ctemplate',
+        '<(AOS)/common/common.gyp:once',
+        '<(AOS)/common/common.gyp:scoped_fd',
+        '<(AOS)/build/aos.gyp:logging',
+      ],
+      'export_dependent_settings': [
+        '<(EXTERNALS):libevent',
+        '<(EXTERNALS):ctemplate',
+      ],
+    },
+  ],
+}