#include #include #include #include #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; }