212 lines
4.0 KiB
C++
212 lines
4.0 KiB
C++
// Copyright (c) 2012 Bryan Schumaker.
|
|
#include <fs.h>
|
|
#include <idle.h>
|
|
#include <print.h>
|
|
|
|
#include <dirent.h>
|
|
#include <sys/stat.h>
|
|
#include <stdlib.h>
|
|
#include <fstream>
|
|
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<string> &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<string> &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<string> &file_list)
|
|
{
|
|
list<string> files;
|
|
list<string>::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<string> files;
|
|
list<string>::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 */
|