#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "common.h"
#include "debug.h"
#include "utils.h"
enum
{
DEBUG_UTILS = false,
MODE_BASICMODE_MASK = 0xF
};
static bool dirmode_test(ulong self, ulong mode)
{
return (self & mode) == mode;
}
bool dirmode_isexec(ulong self)
{
return dirmode_test(self, DMEXEC);
}
bool dirmode_isread(ulong self)
{
return dirmode_test(self, DMREAD);
}
bool dirmode_iswrite(ulong self)
{
return dirmode_test(self, DMWRITE);
}
bool dirmode_isdir(ulong self)
{
return dirmode_test(self, DMDIR);
}
static int mode_basicmode(int self)
{
return self & MODE_BASICMODE_MASK;
}
bool mode_isexec(int self)
{
return mode_basicmode(self) == OEXEC;
}
bool mode_isread(int self)
{
return mode_basicmode(self) == OREAD;
}
bool mode_iswrite(int self)
{
return mode_basicmode(self) == OWRITE;
}
bool mode_isread_write(int self)
{
return mode_basicmode(self) == ORDWR;
}
bool mode_includes_write(int self)
{
return mode_iswrite(self) || mode_isread_write(self);
}
bool mode_includes_read(int self)
{
return mode_isread(self) || mode_isread_write(self);
}
bool perm_isread(ulong self)
{
return (self & DMREAD) != 0;
}
bool perm_iswrite(ulong self)
{
return (self & DMWRITE) != 0;
}
bool perm_isexec(ulong self)
{
return (self & DMEXEC) != 0;
}
bool perm_isappend(ulong self)
{
return (self & DMAPPEND) != 0;
}
bool perm_isdir(ulong self)
{
return (self & DMDIR) != 0;
}
bool perm_isexclusive(ulong self)
{
return (self & DMEXCL) != 0;
}
bool qid_isdir(Qid *qid)
{
assert_valid(qid);
return qid->type == QTDIR;
}
void qid_dump(Qid *qid)
{
assert_valid(qid);
NOISE(DEBUG_UTILS, "qid type: 0x%uX vers: 0x%ulX path: 0x%ullX",
qid ->type, qid->vers, qid->path);
}
static void dir_clone_append_string(char **field, char **current, char *source)
{
assert_valid(field);
assert_valid(current);
assert_valid(source);
*field = *current;
strcpy(*field, source);
*current += strlen(source) + 1;
}
static void dir_clone_copy_strings(Dir *self, Dir *result)
{
char *stringcurrent = (char*)(result + 1);
assert_valid(self);
assert_valid(result);
dir_clone_append_string(&(result->name), &stringcurrent, self->name);
dir_clone_append_string(&(result->uid), &stringcurrent, self->uid);
dir_clone_append_string(&(result->gid), &stringcurrent, self->gid);
dir_clone_append_string(&(result->muid), &stringcurrent, self->muid);
}
static void dir_clone_copy(Dir *self, Dir *result)
{
assert_valid(self);
assert_valid(result);
memcpy(result, self, sizeof(*self));
dir_clone_copy_strings(self, result);
}
static ulong dir_clone_block_size(Dir *self)
{
assert_valid(self);
return sizeof(*self) +
(strlen(self->name) + 1) + (strlen(self->uid) + 1) +
(strlen(self->gid) + 1) + (strlen(self->muid) + 1);
}
/**
* @todo write test case.
*/
Dir *dir_clone(Dir *self)
{
Dir *result;
assert_valid(self);
result = (Dir *)emalloc_fs(dir_clone_block_size(self));
dir_clone_copy(self, result);
return result;
}
void dir_free(Dir *self)
{
if(self == nil)
{
return;
}
free(self->name);
free(self->uid);
free(self->gid);
free(self->muid);
free(self);
}
void dir_copy(Dir *self, Dir *copy)
{
assert_valid(self);
assert_valid(copy);
memcpy(copy, self, sizeof(*self));
copy->uid = estrdup_fs(self->uid);
copy->gid = estrdup_fs(self->gid);
copy->name = estrdup_fs(self->name);
copy->muid = estrdup_fs(self->muid);
}
void dir_dump(Dir *self)
{
assert_valid(self);
NOISE(DEBUG_UTILS, "dir: %s type: %uhd dev: %ud length: %lld mode: 0x%ulX",
self->name, self->type, self->dev, self->length, self->mode);
}
void fcall_dump(Fcall *self)
{
assert_valid(self);
NOISE(DEBUG_UTILS, "type: %ud fid: %ud tag: %ud",
self->type, self->fid, self->tag);
}
char *last_error(void)
{
static char errormessage[256];
rerrstr(errormessage, sizeof(errormessage));
return errormessage;
}
|