#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <malloc.h>
#ifndef CYGWIN32
#include <unistd.h>
#endif
#include "scripting.h"
#include "mud.h"
extern int errno;
DIRFILE_ENTRY * dirfile_root;
DIRFILE_ENTRY * new_dir_entry()
{
DIRFILE_ENTRY * new;
new = malloc(sizeof(*new));
new->name = strdup("");
new->creator = strdup("");
new->vSecurity = 5;
new->eSecurity = 5;
new->cSecurity = 5;
new->parent = NULL;
new->contents = NULL;
return new;
}
void free_dir_entry(DIRFILE_ENTRY *target)
{
free(target->name);
free(target->creator);
/*free the list stuff, dont' need it yet, can't delete dir's.*/
free(target);
}
bool read_dirfile(LIST * target,const char * path, DIRFILE_ENTRY * parent)
{
FILE * fp;
char filename[MAX_BUFFER];
char buf[MAX_BUFFER];
char * word;
ITERATOR pIter;
bool done = FALSE;
bool found;
DIRFILE_ENTRY *current;
sprintf(filename, "%s/dir", path);
if ((fp = fopen(filename, "r")) == NULL)
return FALSE;
word = fread_word(fp);
while (!done)
{
found = FALSE;
switch (word[0])
{
case 'B':
current = new_dir_entry();
current->contents = NULL;
if (parent == NULL)
{
/*If a directory is somehow orphaned, link it to root.*/
current->parent = dirfile_root;
}
else
{
current->parent = parent;
}
current->locked = FALSE;
free(current->name);
free(current->creator);
found = TRUE;
break;
case 'n':
SREAD("name", current->name);
break;
case 'c':
SREAD("creator", current->creator);
IREAD("csec", current->cSecurity);
break;
case 'e':
IREAD("esec", current->eSecurity);
break;
case 't':
IREAD("type", current->type);
break;
case 'v':
IREAD("vsec", current->vSecurity);
break;
case 'E':
if (!strcasecmp(word, "EOF")) {done = TRUE; found = TRUE; break;}
if (!strcasecmp(word, "END"))
{
AttachToList(current, target);
sprintf(buf, "%s/%s", path, current->name);
current->realpath = strdup(buf);
found = TRUE;
}
break;
}
if (!found)
{
bug("read_dirfile: unexpected '%s' in %s's dirfile.", word, path);
}
/* read one more */
if (!done)
{
word = fread_word(fp);
}
}
fclose(fp);
AttachIterator(&pIter, target);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (current->type == DIRFILE_TYPE_DIR && strcasecmp(current->name, "."))
{
sprintf(buf, "%s/%s", path, current->name);
if (current->contents == NULL)
current->contents = AllocList();
read_dirfile(current->contents, buf, current);
}
}
DetachIterator(&pIter);
return TRUE;
}
void init_dir_structure()
{
dirfile_root = new_dir_entry();
free(dirfile_root->name);
dirfile_root->name = strdup("/");
dirfile_root->contents = AllocList();
dirfile_root->realpath = SCRIPT_DIR;
if (!read_dirfile(dirfile_root->contents, SCRIPT_DIR, NULL))
log_string("read_dirfile failed!");
}
DIRFILE_ENTRY * get_entry_by_name(const char * name, LIST * target)
{
ITERATOR pIter;
DIRFILE_ENTRY *current;
if (target == NULL)
return NULL;
AttachIterator(&pIter, target);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (!strcasecmp(current->name, name))
{
DetachIterator(&pIter);
return current;
}
}
DetachIterator(&pIter);
return NULL;
}
DIRFILE_ENTRY * get_dirfile_from_path(const char * path, DIRFILE_ENTRY *start, D_MOBILE *dMob)
{
char *lPath;
char *token;
DIRFILE_ENTRY *current;
char buf[MAX_BUFFER];
lPath = strdup(path);
token = strtok(lPath, "/");
if (lPath[0] != '/')
{
current = start;
}
else
{
current = dirfile_root;
if (token == NULL)
{
free(lPath);
return current;
}
}
if (!strcasecmp(token, "~"))
{
sprintf(buf, "/home/%s",dMob->name );
current = get_dirfile_from_path(buf, NULL, NULL);
token = strtok(NULL, "/");
}
while (token != NULL)
{
if (strcasecmp(token, ".."))
current = get_entry_by_name(token, current->contents);
else
current = current->parent;
if (current == NULL)
{
return NULL;
}
token = strtok(NULL, "/");
}
free(lPath);
return current;
}
DIRFILE_ENTRY * get_dirfile_from_real_path(const char* path, D_MOBILE *dMob)
{
char * nPath;
nPath = strpbrk(path, "/");
nPath++;
nPath = strdup(nPath);
nPath = strpbrk(nPath, "/");
return get_dirfile_from_path(nPath, NULL, dMob);
}
void write_dirfile(LIST * target)
{
DIRFILE_ENTRY * current;
ITERATOR pIter;
char filename[MAX_BUFFER];
FILE *fp;
current = get_entry_by_name(".", target);
if (current == NULL)
{
bug("Null current in write_dirfile");
return;
}
if (current->type == DIRFILE_TYPE_FILE)
{
bug("Wrong type in write_dirfile");
return;
}
sprintf(filename, "%s/dir", current->realpath);
if ((fp = fopen(filename, "w")) == NULL)
{
bug("Unable to write to %s's dirfile", current->realpath);
return;
}
AttachIterator(&pIter, target);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
fprintf(fp, "BEGIN \n");
fprintf(fp, "name %s~\n", current->name);
fprintf(fp, "creator %s~\n", current->creator);
fprintf(fp, "vsec %d\n", current->vSecurity);
fprintf(fp, "esec %d\n", current->eSecurity);
fprintf(fp, "csec %d\n", current->cSecurity);
fprintf(fp, "type %d\n", current->type);
fprintf(fp, "END \n");
}
fprintf(fp, "EOF ");
fclose(fp);
}
void handle_file_editing(D_MOBILE *dMob, char *arg)
{
FILE *fp;
int line;
char filename[MAX_BUFFER];
char cmd[MAX_BUFFER];
char * orig;
char arg2[MAX_BUFFER];
orig = strdup(arg);
arg = one_arg(arg, cmd);
if (!strcasecmp(cmd, "*"))
{
text_to_mobile(dMob, "Leaving editor, file unsaved.\n\r");
dMob->editing->locked = FALSE;
buffer_free(dMob->editing->data);
dMob->editing = NULL;
free(orig);
return;
}
if (!strcasecmp(cmd, "@"))
{
sprintf(filename, "%s",dMob->editing->realpath);
text_to_mobile(dMob, "Leaving editor, file saved.\n\r");
if ((fp = fopen(filename, "w")) == NULL)
{
bug("Unable to write to file %s", dMob->editing->realpath);
return;
}
fprintf(fp, "%s", dMob->editing->data->data);
fclose(fp);
dMob->editing->locked = FALSE;
buffer_free(dMob->editing->data);
dMob->editing = NULL;
free(orig);
return;
}
if (!strcasecmp(cmd, ".s"))
{
free(orig);
numbered_buffer_to_mobile(dMob->editing->data, dMob);
return;
}
if (!strcasecmp(cmd, ".bl"))
{
free(orig);
buffer_strcat(dMob->editing->data, "\n");
return;
}
if (!strcasecmp(cmd, ".ld"))
{
free(orig);
line = atoi(arg);
log_string("%d is the line.", line);
if (line == 0)
{
text_to_mobile(dMob, "syntax: .ld <line number>\n\r");
}
else
{
buffer_remline(dMob->editing->data, line);
text_to_mobile(dMob, "Ok.\n\r");
}
return;
}
if (!strcasecmp(cmd, ".li"))
{
free(orig);
arg = one_arg(arg, arg2);
line = atoi(arg2);
if (line == 0 || arg[0] == '\0')
{
text_to_mobile(dMob, "syntax: .li <line number> <text>\n\r");
}
else
{
buffer_insertline(dMob->editing->data, line, arg);
text_to_mobile(dMob, "Ok.\n\r");
}
return;
}
if (!strcasecmp(cmd, ".lr"))
{
free(orig);
arg = one_arg(arg, arg2);
line = atoi(arg2);
if (line == 0 || arg[0] == '\0')
{
text_to_mobile(dMob, "syntax: .lr <line number> <text>\n\r");
}
else
{
buffer_replaceline(dMob->editing->data, line, arg);
text_to_mobile(dMob, "Ok.\n\r");
}
return;
}
buffer_strcat(dMob->editing->data, orig);
/*buffer_strcat(dMob->editing->data, "\n");*/
free(orig);
}
bool file_exists(const char * filename)
{
struct stat fStats;
if (stat(filename, &fStats) == -1)
{
if (errno == ENOENT)
return FALSE;
}
if (S_ISREG(fStats.st_mode))
return TRUE;
return FALSE;
}
void load_code(LIST * target)
{
ITERATOR pIter;
DIRFILE_ENTRY *current;
if (target == NULL)
return;
AttachIterator(&pIter, target);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (current->type == DIRFILE_TYPE_FILE && is_postfix(current->name, ".lua"))
{
log_string("loading file: %s ", current->realpath);
if (luaL_loadfile(lua, current->realpath) == 0)
{
if (lua_pcall(lua, 0, 0, 0) != 0)
{
log_string("error running file. error: %s", lua_tostring(lua, -1));
}
}
else
{
log_string("Error loading file. Error: %s", lua_tostring(lua, -1));
}
}
}
DetachIterator(&pIter);
/*Split into two loops so code is loaded one directory at a time, top down.*/
AttachIterator(&pIter, target);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (!strcmp(current->name, "home"))
{
log_string("Skipping home dir.");
continue;
}
if (current->type == DIRFILE_TYPE_DIR)
{
load_code(current->contents);
}
}
DetachIterator(&pIter);
}
bool can_access(D_MOBILE *dMob, DIRFILE_ENTRY *target, int type)
{
bool access = FALSE;
if (!strcasecmp(dMob->name, target->creator))
access = TRUE;
switch (type)
{
case ESECURITY:
if (dMob->level >= target->eSecurity)
access=TRUE;
break;
case VSECURITY:
if (dMob->level >= target->vSecurity)
access=TRUE;
break;
case CSECURITY:
if (dMob->level >= target->cSecurity)
access=TRUE;
break;
}
return access;
}
/* shell commands below here. */
void cmd_chmod(D_MOBILE *dMob, char * arg)
{
char filename[MAX_BUFFER];
char type[MAX_BUFFER];
DIRFILE_ENTRY * file;
int rank;
arg = one_arg(arg, filename);
arg = one_arg(arg, type);
rank = atoi(arg);
file = get_entry_by_name(filename, dMob->curdir->contents);
if (file == NULL)
{
text_to_mobile(dMob, "File not found.\n]r");
return;
}
if (rank > dMob->level)
{
text_to_mobile(dMob, "You cannot set the rank higher than your own.\n\r");
return;
}
if (!can_access(dMob, file, ESECURITY))
{
text_to_mobile(dMob, "Insufficent security");
return;
}
switch(type[0])
{
case 'v':
case 'V':
file->vSecurity = rank;
break;
case 'E':
case 'e':
file->eSecurity = rank;
break;
case 'C':
case 'c':
file->cSecurity = rank;
break;
default:
text_to_mobile(dMob, "Incorrect type, use v,c, or e.\n\r");
return;
}
text_to_mobile(dMob, "Value set.\n\r");
write_dirfile(dMob->curdir->contents);
}
void cmd_chown(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
char arg2[MAX_BUFFER];
D_MOBILE *target;
arg = one_arg(arg, arg2);
if (arg[0] == '\0' || arg2[0] == '\0')
{
text_to_mobile(dMob,"Syntax: chown <target> <new owner>\n\r");
return;
}
current = get_entry_by_name(arg2, dMob->curdir->contents);
target = get_mobile_by_name(arg);
if (target == NULL)
{
text_to_mobile(dMob, "Set owner to who?\n\r");
return;
}
if (!can_access(dMob, current, ESECURITY))
{
text_to_mobile(dMob, "Insufficent security");
return;
}
free(current->creator);
current->creator = strdup(target->name);
text_to_mobile(dMob, "Owner changed.\n\r");
write_dirfile(dMob->curdir->contents);
}
void cmd_mkcore(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
if (arg[0] == '\0')
{
text_to_mobile(dMob,"Syntax: mkcore <target>\n\r");
return;
}
current = get_entry_by_name(arg, dMob->curdir->contents);
if (current == NULL)
{
text_to_mobile(dMob, "File not found.\n\r");
return;
}
if (!can_access(dMob, current, ESECURITY))
{
text_to_mobile(dMob, "Insufficent security");
return;
}
free(current->creator);
current->creator = strdup("core");
write_dirfile(dMob->curdir->contents);
text_to_mobile(dMob, "File added to core.\n\r");
}
void cmd_demote(D_MOBILE *dMob, char *arg)
{
D_MOBILE * target;
char buf[MAX_BUFFER];
int rank;
arg = one_arg(arg, buf);
rank = atoi(arg);
if (arg[0] == '\0')
{
text_to_mobile(dMob, "Syntax: demote <target> <rank>\n\r");
return;
}
target = get_mobile_by_name(buf);
if (target == NULL)
{
text_to_mobile(dMob, "They're not here.\n\r");
return;
}
if (target->level >= dMob->level)
{
text_to_mobile(dMob, "You can't demote them.\n\r");
log_string("%s tried to demote %s to rank %d", dMob->name,target->name, rank);
return;
}
if (rank < 1)
rank = 1;
target->level = rank;
text_to_mobile(dMob, "Ok.\n\r");
text_to_mobile(target, "You have been demoted.\n\r");
}
void cmd_promote(D_MOBILE *dMob, char *arg)
{
D_MOBILE * target;
char buf[MAX_BUFFER];
char path[MAX_BUFFER];
struct stat stats;
DIRFILE_ENTRY *home;
DIRFILE_ENTRY *new;
DIRFILE_ENTRY *first;
int rank;
arg = one_arg(arg, buf);
rank = atoi(arg);
if (buf[0] =='\0' || rank == 0)
{
text_to_mobile(dMob, "Promote who to what rank?\n\r");
return;
}
/* if (rank >= dMob->level)
{
text_to_mobile(dMob, "You can't promote people to that level.\n\r");
return;
}*/
target = get_mobile_by_name(buf);
if (target == NULL)
{
text_to_mobile(dMob, "No such player found.\n\r");
return;
}
if (target == dMob)
{
text_to_mobile(dMob, "Nice try.\n\r");
log_string("%s tried to promote themselves to level %d", dMob->name, rank);
return;
}
if (target->level > rank)
{
text_to_mobile(dMob, "Use the demote command.\n\r");
return;
}
sprintf(path, "%s/%s", IMP_HOME_DIR, target->name);
home = get_dirfile_from_path (path, NULL, NULL);
target->level = rank;
if (home != NULL)
{
text_to_mobile(dMob, "That home directory is already in use, attaching player.\n\r");
text_to_mobile(target, "You have been promoted to shell access.\n\r");
log_string("%s has been promoted to level %d.", target->name, target->level);
}
home = get_dirfile_from_path(IMP_HOME_DIR, NULL, NULL);
new = new_dir_entry();
new->parent =home;
AttachToList(new, home->contents);
sprintf(buf, "%s/%s", home->realpath, target->name );
new->name = strdup(target->name);
new->creator = strdup(target->name);
new->cSecurity = target->level;
new->vSecurity = target->level;
new->eSecurity = target->level;
new->type = DIRFILE_TYPE_DIR;
new->contents = AllocList();
new->realpath = strdup(buf);
log_string(buf);
/* . entry in new dir.*/
first = new_dir_entry();
first->name = strdup(".");
first->cSecurity = target->level;
first->vSecurity = target->level;
first->eSecurity = target->level;
first->type = DIRFILE_TYPE_DIR;
first->realpath = strdup(buf);
AttachToList(first, new->contents);
stats.st_mode = S_IRWXU;
mkdir(buf, stats.st_mode);
write_dirfile(home->contents);
write_dirfile(new->contents);
text_to_mobile(dMob, "They have been promoted.\n\r");
text_to_mobile(target, "You have been promoted to shell access.\n\r");
log_string("%s has been promoted to rank %d.", target->name, target->level);
return;
}
void cmd_edit(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
FILE *fp;
char * file;
/*int c;
char buf[MAX_BUFFER];*/
if (dMob->curdir == NULL)
{
log_string("Null curdir in cmd_edit for mobile %d", dMob->name);
return;
}
current = get_entry_by_name(arg, dMob->curdir->contents);
if (current == NULL || current->type == DIRFILE_TYPE_DIR)
{
text_to_mobile(dMob, "File not found.\n\r");
return;
}
if (!can_access(dMob, current,ESECURITY))
{
text_to_mobile(dMob, "Insufficent security.\n\r");
return;
}
dMob->editing = current;
dMob->editing->data = buffer_new(MAX_BUFFER);
buffer_clear(dMob->editing->data);
if (file_exists(dMob->editing->realpath))
{
if ((fp = fopen(dMob->editing->realpath, "r")) == NULL)
{
text_to_mobile(dMob, "Error viewing file.\n\r");
return;
}
file= read_lua_file(fp);
buffer_strcat(dMob->editing->data, file);
fclose(fp);
}
numbered_buffer_to_mobile(dMob->editing->data, dMob);
current->locked = TRUE;
}
void cmd_ls(D_MOBILE *dMob, char * arg)
{
ITERATOR pIter;
DIRFILE_ENTRY * current;
char buf[MAX_BUFFER];
if (arg[0] =='\0')
{
if (dMob->curdir == NULL) /*root dir.*/
{
log_string("Null curdir for mob %s", dMob->name);
}
else
AttachIterator(&pIter, dMob->curdir->contents);
text_to_mobile(dMob, " E V C Creator\n\r");
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (current->type == DIRFILE_TYPE_DIR)
{
sprintf(buf, "#B%-20s %d %d %d %s\n\r", current->name, current->eSecurity, current->vSecurity, current->cSecurity, current->creator);
}
else
{
sprintf(buf, "#r%-20s %d %d %d %s\n\r", current->name, current->eSecurity, current->vSecurity, current->cSecurity, current->creator);
}
text_to_mobile(dMob, buf);
}
}
else
{
current = get_dirfile_from_path(arg, dMob->curdir, NULL);
if (current == NULL || current->type == DIRFILE_TYPE_FILE)
{
text_to_mobile(dMob,"Directory not found.");
return;
}
AttachIterator(&pIter, current->contents);
while ((current = (DIRFILE_ENTRY *) NextInList(&pIter)) != NULL)
{
if (current->type == DIRFILE_TYPE_DIR)
{
sprintf(buf, "#B%s\n\r", current->name);
}
else
{
sprintf(buf, "#r%s\n\r", current->name);
}
text_to_mobile(dMob, buf);
}
}
}
void cmd_rmdir(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * target;
DIR * dir;
struct dirent * entry;
int count;
char buf[MAX_BUFFER];
target = get_entry_by_name(arg, dMob->curdir->contents);
if (target == NULL || target->type == DIRFILE_TYPE_FILE)
{
text_to_mobile(dMob, "That directory does not exist.\n\r");
return;
}
if (!can_access(dMob, target, CSECURITY))
{
text_to_mobile(dMob, "You do not have enough security.\n\r");
return;
}
if (target == dMob->curdir)
{
text_to_mobile(dMob, "Now how would that work??\n\r");
return;
}
/*check emptyness except for Dir file.
* If it's the only file there, remove it, so rmdir can work.
*/
count = 0;
dir=opendir(target->realpath);
while ((entry = readdir(dir))!= NULL)
{
if (!strcasecmp(".", entry->d_name) || !strcasecmp("..", entry->d_name) || !strcasecmp("dir", entry->d_name))
{
continue;
}
else count++;
}
closedir(dir);
if (count >0)
{
text_to_mobile(dMob, "That directory is not empty.\n\r");
return;
}
else
{
sprintf(buf, "%s/dir",target->realpath);
if (unlink(buf) == -1)
{
bug("Error deleting file: %s", buf);
}
}
if (rmdir(target->realpath) != 0 )
{
if (errno == EEXIST || errno == ENOTEMPTY)
{
text_to_mobile(dMob, "The directory is not empty.\n\r");
return;
}
bug("Error deleting file: %s", target->realpath);
}
DetachFromList(target, dMob->curdir->contents);
write_dirfile(dMob->curdir->contents);
free_dir_entry(target);
}
void cmd_mkdir(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
DIRFILE_ENTRY * new;
DIRFILE_ENTRY * first;
struct stat stats;
char buf[MAX_BUFFER];
current = dMob->curdir;
new = get_entry_by_name(arg, current->contents);
if (new != NULL)
{
text_to_mobile(dMob, "That name is taken.\n\r");
return;
}
if (can_access(dMob, current, CSECURITY))
{
new = new_dir_entry();
new->parent =current;
AttachToList(new, current->contents);
sprintf(buf, "%s/%s", current->realpath, arg );
new->name = strdup(arg);
new->creator = strdup(dMob->name);
new->cSecurity = dMob->level;
new->vSecurity = dMob->level;
new->eSecurity = dMob->level;
new->type = DIRFILE_TYPE_DIR;
new->contents = AllocList();
new->realpath = strdup(buf);
log_string(buf);
/* . entry in new dir.*/
first = new_dir_entry();
first->name = strdup(".");
first->cSecurity = dMob->level;
first->vSecurity = dMob->level;
first->eSecurity = dMob->level;
first->type = DIRFILE_TYPE_DIR;
first->realpath = strdup(buf);
AttachToList(first, new->contents);
stats.st_mode = S_IRWXU;
mkdir(buf, stats.st_mode);
write_dirfile(current->contents);
write_dirfile(new->contents);
return;
}
log_string("insufficient security.");
}
void cmd_touch(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
DIRFILE_ENTRY * new;
char buf[MAX_BUFFER];
current = dMob->curdir;
new = get_entry_by_name(arg, current->contents);
if (new != NULL)
{
text_to_mobile(dMob, "That name is taken.\n\r");
return;
}
if (can_access(dMob, current, CSECURITY))
{
new = new_dir_entry();
new->parent =current;
AttachToList(new, current->contents);
sprintf(buf, "%s/%s", current->realpath, arg );
new->name = strdup(arg);
new->creator = strdup(dMob->name);
new->cSecurity = dMob->level;
new->vSecurity = dMob->level;
new->eSecurity = dMob->level;
new->type = DIRFILE_TYPE_FILE;
new->realpath = strdup(buf);
log_string(buf);
write_dirfile(current->contents);
return;
}
log_string("insufficient security.");
}
void cmd_cd(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * current;
if (!strcasecmp(arg, ".."))
{
if (dMob->curdir->parent ==NULL)
{
text_to_mobile(dMob,"No such path.\n\r");
return;
}
if (can_access(dMob, dMob->curdir->parent, VSECURITY))
{
dMob->curdir = dMob->curdir->parent;
return;
}
else
{
text_to_mobile(dMob,"You're not allowed to view that directory.\n\r");
return;
}
}
current = get_dirfile_from_path(arg, dMob->curdir, dMob);
if (current == NULL || current->type == DIRFILE_TYPE_FILE)
{
text_to_mobile(dMob, "path not found.");
return;
}
if (can_access(dMob, current, VSECURITY))
{
dMob->curdir = current;
}
else
{
text_to_mobile(dMob,"You're not allowed to view that directory.\n\r");
return;
}
}
void cmd_rm(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * target;
target = get_entry_by_name(arg, dMob->curdir->contents);
if (target == NULL || target->type == DIRFILE_TYPE_DIR)
{
text_to_mobile(dMob, "That file does not exist.\n\r");
return;
}
if (!can_access(dMob, target, CSECURITY))
{
text_to_mobile(dMob, "You do not have enough security.\n\r");
return;
}
if (target->locked)
{
text_to_mobile(dMob, "That file is busy.\n\r");
return;
}
DetachFromList(target, dMob->curdir->contents);
write_dirfile(dMob->curdir->contents);
if (file_exists(target->realpath) == TRUE && unlink(target->realpath) == -1)
{
bug("Error deleting file: %s", target->realpath);
}
free_dir_entry(target);
}
void cmd_view(D_MOBILE *dMob, char * arg)
{
DIRFILE_ENTRY * target;
FILE *fp;
char * file;
target = get_entry_by_name(arg, dMob->curdir->contents);
if (target == NULL || target->type == DIRFILE_TYPE_DIR)
{
text_to_mobile(dMob, "That file does not exist.\n\r");
return;
}
if (!can_access(dMob, target, VSECURITY))
{
text_to_mobile(dMob, "You do not have enough security.\n\r");
return;
}
if ((fp = fopen(target->realpath, "r")) == NULL)
{
text_to_mobile(dMob, "Error viewing file.\n\r");
return;
}
file = read_lua_file(fp);
text_to_mobile(dMob, file);
fclose(fp);
}
void cmd_reload(D_MOBILE *dMob, char *arg)
{
/*TODO: Add refresh info to lua class superstructure*/
DIRFILE_ENTRY * current;
current = get_entry_by_name(arg, dMob->curdir->contents);
if (current == NULL || current->type == DIRFILE_TYPE_DIR)
{
text_to_mobile(dMob, "File not found.\n\r");
return;
}
if (!can_access(dMob, current, ESECURITY))
{
text_to_mobile(dMob, "Insufficent security.\n\r");
return;
}
log_string("reloading file: %s ", current->realpath);
if (luaL_loadfile(lua, current->realpath) == 0)
{
if (lua_pcall(lua, 0, 0, 0) != 0)
{
log_string("error while reloading file. error: %s", lua_tostring(lua, -1));
}
}
else
{
log_string("Error reloading file. Error: %s", lua_tostring(lua, -1));
}
}
void cmd_return(D_MOBILE *dMob, char * arg)
{
dMob->shell = FALSE;
}