// Copyright (c) 2012 Bryan Schumaker. #include #include #include #include #include #include #include using namespace std; static string appdir; static mode_t dirmode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; static bool pipe_opened = false; static void make_dir(const string &path) { println("Making directory: " + path); mkdir(path.c_str(), dirmode); } static void handle_entry(string &dir, list &file_list, struct dirent *dirp) { struct stat stat; string name = dirp->d_name; if (name == "." || name == "..") return; name = dir + "/" + name; if (lstat(name.c_str(), &stat) == 0) { if (S_ISDIR(stat.st_mode)) libsaria::list_dir(name, file_list); else file_list.push_back(name); } } static bool compare_files(string &one, string &two) { unsigned int a = atoi(one.c_str()); unsigned int b = atoi(two.c_str()); return a < b; } struct ReadData { string filepath; void (*func)(ifstream &); }; static void read_cb(void *d) { ifstream stream; struct ReadData *data = (struct ReadData *)d; stream.open(data->filepath.c_str()); data->func(stream); stream.close(); delete data; } struct WriteData { string filepath; void (*func)(ofstream &, void *); void *data; }; static void write_cb(void *d) { ofstream stream; struct WriteData *data = (struct WriteData *)d; stream.open(data->filepath.c_str()); data->func(stream, data->data); stream.close(); delete data; } namespace libsaria { bool exists(const string &filepath) { struct stat stat; return lstat(filepath.c_str(), &stat) == 0; } void list_dir(string &dir, list &file_list) { DIR *dp; struct dirent *dirp; dp = opendir(dir.c_str()); if (dp == NULL) return; do { dirp = readdir(dp); if (dirp) handle_entry(dir, file_list, dirp); } while (dirp != NULL); closedir(dp); } void app::list_dir(const string &dir, list &file_list) { list files; list::iterator it; string d = appdir + "/" + dir; libsaria::list_dir(d, files); /* Strip out appdir information */ for (it = files.begin(); it != files.end(); it++) file_list.push_back( (*it).substr(d.size() + 1) ); } unsigned int app::read_numdir(const string &dir, void (*func)(ifstream &)) { list files; list::iterator it; list_dir(dir, files); if (files.size() == 0) return 0; files.sort(compare_files); for (it = files.begin(); it != files.end(); it++) { println("Reading path: " + dir + "/" + (*it)); read(dir + "/" + (*it), func); } return atoi(files.back().c_str()) + 1; } void app::mkdir(const string &dir) { string d = appdir + "/" + dir; make_dir(d.c_str()); } void app::rm(const string &file) { string f = appdir + "/" + file; remove(f.c_str()); } void app::init() { string home = getenv("HOME"); appdir = home + "/.ocarina"; #ifdef DEBUG appdir += "-debug"; #endif make_dir(appdir.c_str()); } void app::save(string file, void (*func)(ofstream &, void *), void *d) { struct WriteData *data = new struct WriteData; data->filepath = appdir + "/" + file; data->func = func; data->data = d; idle::schedule(write_cb, data); } void app::read(string file, void (*func)(ifstream &)) { struct ReadData *data = new struct ReadData; data->filepath = appdir + "/" + file; data->func = func; idle::schedule(read_cb, data); } void app::read_now(string file, void (*func)(ifstream &)) { ifstream stream; stream.open((appdir + "/" + file).c_str()); func(stream); stream.close(); } void app::open_pipe() { string file = appdir + "/pipe"; if (!exists(file)) { mkfifo(file.c_str(), 0644); pipe_opened = true; } else { println("Pipe file: %s already exists, pipe not opened!", file.c_str()); } } void app::close_pipe() { string file = appdir + "/pipe"; if (pipe_opened && exists(file)) rm("pipe"); } string app::pipe_file() { if (pipe_opened) return appdir + "/pipe"; return ""; } } /* Namespace: libsaria */