|
From: Peep P. <so...@us...> - 2004-07-24 17:58:59
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32302 Modified Files: dfuns.c Log Message: New dfuns: shutdown, master, get_dir, write_file, implode, explode, do_command, query_verb, add_command, find_player, this_player; rearranged order into categories Index: dfuns.c =================================================================== RCS file: /cvsroot/agd/server/src/dfuns.c,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- dfuns.c 23 Jul 2004 17:18:35 -0000 1.25 +++ dfuns.c 24 Jul 2004 17:58:50 -0000 1.26 @@ -2,6 +2,9 @@ #include <stdio.h> #include <time.h> #include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> #include <netdb.h> /* for gethostbyaddr() */ #include "arch.h" @@ -17,6 +20,7 @@ extern player_t *this_player; extern object_t *this_ob, *previous_ob; +extern object_t *master; extern list_t players; extern list_t all_objects; @@ -37,7 +41,8 @@ dfptr[i] = decl[i].fun; num_arg = decl[i].num_arg; - args = xmalloc(sizeof(int) * num_arg); + if(num_arg) + args = xmalloc(sizeof(int) * num_arg); for(j=0;j<num_arg;j++) { args[j] = decl[i].args[j]; @@ -46,6 +51,7 @@ } } +/* Interactives. */ void do_write(char *s) { if(this_player) @@ -63,7 +69,7 @@ for(p = &all_objects; p; p = p->next) { object_t *ob = p->data; - if(ob->iaob && ob != this_player->ob) { + if(ob->iaob/* && ob != this_player->ob*/) { tell_object(ob, s); } } @@ -76,6 +82,28 @@ push_void(); } +void df_shout(void) +{ + shout(fp[0].u.s); + pop_stack(); + push_void(); +} + +void df_tell_object(void) +{ + tell_object(fp[0].u.ob, fp[1].u.s); + pop_stack(); pop_stack(); + push_void(); +} + +void df_interactive(void) +{ + object_t *ob = fp->u.ob; + int ret = ob && ob->iaob; + pop_stack(); + push_int(ret); +} + void df_input_to(void) { if(this_player) { @@ -92,6 +120,17 @@ push_void(); } +void df_query_idle(void) +{ + int ret; + if(!fp->u.ob->iaob) + ret = -1; + else + ret = time(NULL) - fp->u.ob->iaob->conn.last_active; + pop_stack(); + push_int(ret); +} + char *get_ip(object_t *ob) { if(!ob->iaob) @@ -99,7 +138,7 @@ return inet_ntoa(ob->iaob->conn.addr.sin_addr); } -void df_query_ip(void) +void df_query_ip_number(void) { char *s; s = get_ip(fp->u.ob); @@ -107,7 +146,7 @@ push_string(s, ST_STATIC); } -void df_query_hostname(void) +void df_query_ip_name(void) { char *s; struct hostent *he; @@ -125,17 +164,117 @@ push_string(s, ST_STATIC); } -void df_shout(void) +void df_users(void) { - shout(fp[0].u.s); + list_t *l; + array_t *ret; + ret = xmalloc(sizeof(array_t)); + init_array(ret); + for(l=&players;l;l=l->next) { + player_t *pl = l->data; + ret->length++; + ret->data = xrealloc(ret->data, ret->length * sizeof(variable_t)); + ret->data[ret->length-1].type = T_OBJECT; + ret->data[ret->length-1].u.ob = pl->ob; +#ifdef DEBUG + ret->data[ret->length-1].name = NULL; +#endif + } + push_array(ret, T_OBJECT); +} + +void df_this_player(void) +{ + push_object(this_player->ob); +} + +void df_find_player(void) +{ + char *name; + object_t *ret = NULL; + list_t *l; + + name = fp->u.s; + if(!name) { + goto out; + } + + for(l=&players;l;l=l->next) { + player_t *pl; + variable_t *var; + pl = l->data; + push_control_stack(); + fp = sp; + var = apply(pl->ob, "query_name", ""); + if(strcmp(var->u.s, name) == 0) { + ret = pl->ob; + pop_control_stack(1); + goto out; + } else { + pop_control_stack(1); + } + } + +out: pop_stack(); - push_void(); + push_object(ret); } -void df_destruct(void) +void df_add_command(void) { - destruct(fp->u.ob); + int num_arg = sp - fp; + player_t *p; + command_t *cmd; + + if(num_arg < 1) { + runtime("add_command() needs a verb"); + return; + } + if(!this_player) + return; + + p = this_player; + p->num_cmd++; + p->cmds = xrealloc(p->cmds, p->num_cmd * sizeof(command_t)); + cmd = &p->cmds[p->num_cmd-1]; + cmd->verb = xstrdup(fp->u.s); + if(num_arg >= 2) + cmd->fun = xstrdup(fp[1].u.s); + else { + cmd->fun = xmalloc(strlen(cmd->verb) + 4); + sprintf(cmd->fun, "do_%s", cmd->verb); + } +} + +void df_query_verb(void) +{ + command_t *cmd; + + if(!this_player || this_player->this_verb == 0) { + push_string(NULL, ST_MALLOC); + return; + } + + cmd = &this_player->cmds[this_player->this_verb-1]; + push_string(xstrdup(cmd->verb), ST_MALLOC); +} + +void df_do_command(void) +{ + char *cmd = fp->u.s; + + push_control_stack(); + fp++; + do_command(this_player, cmd); + pop_control_stack(1); + pop_stack(); +} + +/* Objects. */ +void df_destruct(void) +{ + destruct(this_ob); push_void(); } @@ -155,42 +294,27 @@ push_object(ret); } -void df_this_object(void) -{ - push_object(this_ob); -} - -void df_previous_object(void) -{ - push_object(previous_ob); -} - void df_clone_object(void) { object_t *ret; push_control_stack(); fp++; - ret = clone_object(csp[/*-1*/0].fp->u.s); + ret = clone_object(csp->fp->u.s); pop_control_stack(1); pop_stack(); push_object(ret); } -void df_interactive(void) +void df_this_object(void) { - object_t *ob = fp->u.ob; - int ret = ob && ob->iaob; - pop_stack(); - push_int(ret); + push_object(this_ob); } -void df_tell_object(void) +void df_previous_object(void) { - tell_object(fp[0].u.ob, fp[1].u.s); - pop_stack(); pop_stack(); - push_void(); + push_object(previous_ob); } void df_exec(void) @@ -221,33 +345,6 @@ push_string(ret, ST_STATIC); } -void df_query_idle(void) -{ - int ret; - if(!fp->u.ob->iaob) - ret = -1; - else - ret = time(NULL) - fp->u.ob->iaob->conn.last_active; - pop_stack(); - push_int(ret); -} - -void df_users(void) -{ - list_t *l; - array_t *ret; - ret = xmalloc(sizeof(array_t)); - init_array(ret); - for(l=&players;l;l=l->next) { - player_t *pl = l->data; - ret->length++; - ret->data = xrealloc(ret->data, ret->length * sizeof(variable_t)); - ret->data[ret->length-1].type = T_OBJECT; - ret->data[ret->length-1].u.ob = pl->ob; - } - push_array(ret, T_OBJECT); -} - /* Numbers. */ void df_random(void) { @@ -267,13 +364,6 @@ } /* Time. */ -void df_uptime(void) -{ - time_t t; - time(&t); - push_int(t - startup_time); -} - void df_time(void) { push_int(time(NULL)); @@ -306,6 +396,13 @@ push_string(buf, ST_STATIC); } +void df_uptime(void) +{ + time_t t; + time(&t); + push_int(t - startup_time); +} + /* Strings. */ void df_strlen(void) { @@ -338,6 +435,75 @@ push_string(s, ST_MALLOC); } +void df_explode(void) +{ + char *str, *delim; + char *bgn, *end; + array_t *ret; + variable_t *tmpv; + int len; + + str = fp->u.s; + delim = fp[1].u.s; + ret = xmalloc(sizeof(array_t)); + init_array(ret); + + bgn = str; + while(1) { + if(!bgn) + break; + + end = strstr(bgn, delim); + if(end) + len = end - bgn; + else + len = strlen(bgn); + + ret->length++; + ret->data = xrealloc(ret->data, ret->length * sizeof(variable_t)); + tmpv = &ret->data[ret->length-1]; + tmpv->type = T_STRING; +#ifdef DEBUG + tmpv->name = NULL; +#endif + tmpv->u.s = xmalloc(len + 1); + strncpy(tmpv->u.s, bgn, len); + tmpv->u.s[len] = '\0'; + + if(!end) + break; + bgn = end + 1; + } + +out: + pop_stack(); pop_stack(); + push_array(ret, ST_MALLOC); +} + +void df_implode(void) +{ + array_t *args; + char *del; + char *ret, *retp; + int i; + + args = fp->u.a; + del = fp[1].u.s; + + ret = xmalloc(1); + ret[0] = '\0'; + retp = ret; + for(i=0;i<args->length;i++) { + char *s = args->data[i].u.s; + ret = xrealloc(ret, strlen(ret) + 1 + strlen(s) + strlen(del)); + retp = ret + strlen(ret); + sprintf(retp, "%s%s", s, (i+1<args->length)?del:""); + } + + pop_stack(); pop_stack(); + push_string(ret, ST_MALLOC); +} + /* Arrays. */ void df_sizeof(void) { @@ -351,17 +517,28 @@ void df_read_file(void) { FILE *f; - char *path; + char *path, *real_path; int file_size; char *file_str, *p; char buf[256]; - path = absolute_path(fp->u.s); - f = fopen(path, "r"); + path = fp->u.s; + if(!legal_path(path)) { + char *buf = xmalloc(strlen(path) + 50); + sprintf(buf, "illegal filename '%s'!", path); + runtime(buf); + free(buf); + return; + } + + real_path = absolute_path(path); + f = fopen(real_path, "r"); if(!f) { char *buf = xmalloc(strlen(path) + 50); sprintf(buf, "can't open '%s' for reading!", path); - runtime_dyn(buf); + runtime(buf); + free(buf); + return; } file_str = NULL; @@ -379,6 +556,121 @@ push_string(file_str, ST_MALLOC); } +void df_write_file(void) +{ + int num_arg; + int ret; + FILE *f; + char *path, *real_path; + char *mode; + + num_arg = sp - fp; + if(num_arg < 1) { + runtime("write_file() needs a filename"); + push_int(1); + return; + } + if(num_arg < 2) { + runtime("write_file() needs a string"); + pop_stack(); + push_int(1); + return; + } + + if(num_arg >= 3 && fp[2].u.i) + mode = "w"; + else + mode = "a"; + + path = fp->u.s; + if(!legal_path(path)) { + char *buf = xmalloc(strlen(path) + 50); + sprintf(buf, "illegal filename '%s'!", path); + runtime(buf); + free(buf); + ret = 1; + goto out; + } + + real_path = absolute_path(path); + f = fopen(real_path, mode); + if(!f) { + char *buf = xmalloc(strlen(path) + 50); + sprintf(buf, "can't open '%s' for %sing!", path, + mode[0] == 'w' ? "writ" : "append"); + runtime(buf); + free(buf); + ret = 1; + goto out; + } + + ret = fprintf(f, "%s", fp[1].u.s); + fclose(f); + +out: + pop_stack(); pop_stack(); + push_int(ret ? 1 : 0); +} + +void df_get_dir(void) +{ + array_t *ret; + char *path, *real_path; + DIR *d; + struct dirent *entry; + + path = fp->u.s; + add_slash(path); + if(!legal_path(path)) { + char *buf; + buf = xmalloc(strlen(path) + 50); + sprintf(buf, "invalid path '%s'", path); + runtime(buf); + free(buf); + return; + } + + ret = xmalloc(sizeof(array_t)); + init_array(ret); + + real_path = absolute_path(path); + d = opendir(real_path); + while(entry = readdir(d)) { + struct stat st; + char *filename; + + if(entry->d_name[0] == '.') + continue; + + filename = xmalloc(strlen(entry->d_name) + strlen(real_path) + 1); + sprintf(filename, "%s%s", real_path, entry->d_name); + if(stat(filename, &st) < 0) { + char *buf; + buf = xmalloc(strlen(path) + strlen(entry->d_name) + 50); + sprintf(buf, "can't stat '%s%s'", path, entry->d_name); + runtime(buf); + ret = NULL; + goto out; + } + if(S_ISDIR(st.st_mode)) + continue; + + ret->length++; + ret->data = xrealloc(ret->data, sizeof(variable_t) * ret->length); + ret->data[ret->length-1].type = T_STRING; + ret->data[ret->length-1].u.s = xstrdup(entry->d_name); +#ifdef DEBUG + ret->data[ret->length-1].name = NULL; +#endif + } + +out: + closedir(d); + + pop_stack(); + push_array(ret, T_STRING); +} + /* Misc. */ void df_throw(void) { @@ -387,6 +679,20 @@ push_void(); } +/* System. */ +void df_master(void) +{ + push_object(master); +} + +void df_shutdown(void) { + if(sp > fp && fp->u.i) + exit(EXIT_DONTBOTHER); + else + exit(EXIT_NORMAL); +} + +/* Debugging. */ void show_all_obj(void) { list_t *p; @@ -400,7 +706,6 @@ puts("----------------------------------------"); } -/* Debugging. */ void df_debug_info(void) { switch(fp->u.i) { |