char * do_parse_mesg_2(int descr, dbref player, dbref what, dbref perms, const char *inbuf, const char *abuf, char *outbuf, int mesgtyp) { char howvar[BUFFER_LEN]; char cmdvar[BUFFER_LEN]; char argvar[BUFFER_LEN]; char tmparg[BUFFER_LEN]; char tmpcmd[BUFFER_LEN]; char *dptr; int mvarcnt = varc; int mfunccnt = funcc; int tmprec_cnt = mesg_rec_cnt; int tmpinst_cnt = mesg_instr_cnt; #ifdef COMPRESS abuf = uncompress(abuf); #endif /* COMPRESS */ *outbuf = '\0'; if (new_mvar("how", howvar)) return outbuf; strcpy(howvar, abuf); if (new_mvar("cmd", cmdvar)) return outbuf; strcpy(cmdvar, match_cmdname); strcpy(tmpcmd, match_cmdname); if (new_mvar("arg", argvar)) return outbuf; strcpy(argvar, match_args); strcpy(tmparg, match_args); #ifdef COMPRESS inbuf = uncompress(inbuf); #endif /* COMPRESS */ dptr = MesgParse(inbuf, outbuf); if (!dptr) { *outbuf = '\0'; } varc = mvarcnt; free_mfuncs(mfunccnt); mesg_rec_cnt = tmprec_cnt; mesg_instr_cnt = tmpinst_cnt; strcpy(match_cmdname, tmpcmd); strcpy(match_args, tmparg); return outbuf; }
const char * mfn_with(MFUNARGS) { char vbuf[BUFFER_LEN]; char *ptr, *valptr; int v, cnt; ptr = MesgParse(argv[0], argv[0]); CHECKRETURN(ptr,"WITH","arg 1"); v = new_mvar(ptr, vbuf); if (v == 1) ABORT_MPI("WITH","Variable name too long"); if (v == 2) ABORT_MPI("WITH","Too many variables already defined"); valptr = MesgParse(argv[1], argv[1]); CHECKRETURN(valptr,"WITH","arg 2"); *buf = '\0'; strcpy(vbuf, valptr); for (cnt = 2; cnt < argc; cnt++) { ptr = MesgParse(argv[cnt],argv[cnt]); if (!ptr) { sprintf(buf, "%s %cWITH%c (%d)", get_mvar("how"), MFUN_LEADCHAR, MFUN_ARGEND, cnt); notify(player, buf); return NULL; } } free_top_mvar(); return ptr; }
const char * mfn_commas(MFUNARGS) { int v, i, count; char *ptr; char buf2[BUFFER_LEN]; char tmp[BUFFER_LEN]; if (argc == 3) ABORT_MPI("COMMAS","Takes 1, 2, or 4 arguments"); ptr = MesgParse(argv[0], argv[0]); CHECKRETURN(ptr,"COMMAS","arg 1"); count = countlitems(argv[0], "\r"); if (count == 0) return ""; if (argc > 1) { ptr = MesgParse(argv[1], argv[1]); CHECKRETURN(ptr,"COMMAS","arg 2"); } else { strcpy(argv[1], " and "); } if (argc > 2) { ptr = MesgParse(argv[2], buf2); CHECKRETURN(ptr,"COMMAS","arg 3"); v = new_mvar(ptr, tmp); if (v == 1) ABORT_MPI("COMMAS","Variable name too long"); if (v == 2) ABORT_MPI("COMMAS","Too many variables already defined"); } *buf = '\0'; for (i = 1; i <= count; i++) { ptr = getlitem(buf2, argv[0], "\r", i); if (argc > 2) { strcpy(tmp, ptr); ptr = MesgParse(argv[3], buf2); CHECKRETURN(ptr,"COMMAS","arg 3"); } strcat(buf, ptr); switch (count - i) { case 0: if (argc > 2) free_top_mvar(); return buf; break; case 1: strcat(buf, argv[1]); break; default: strcat(buf, ", "); break; } } if (argc > 2) free_top_mvar(); return buf; }
const char * mfn_filter(MFUNARGS) { int iter_limit = MAX_MFUN_LIST_LEN; char buf2[BUFFER_LEN]; char tmp[BUFFER_LEN]; char *ptr, *ptr2, *dptr; char *sepin = argv[3]; char *sepbuf = argv[4]; int seplen, v; ptr = MesgParse(argv[0],argv[0]); CHECKRETURN(ptr,"FILTER","arg 1"); v = new_mvar(ptr, tmp); if (v == 1) ABORT_MPI("FILTER","Variable name too long."); if (v == 2) ABORT_MPI("FILTER","Too many variables already defined."); dptr = MesgParse(argv[1],argv[1]); CHECKRETURN(dptr,"FILTER","arg 2"); if (argc > 3) { ptr = MesgParse(sepin,sepin); CHECKRETURN(ptr,"FILTER","arg 4"); if (!*ptr) ABORT_MPI("FILTER","Can't use Null seperator string"); } else { strcpy(sepin, "\r"); } if (argc > 4) { ptr = MesgParse(sepbuf,sepbuf); CHECKRETURN(ptr,"FILTER","arg 5"); } else { strcpy(sepbuf, sepin); } seplen = strlen(sepin); *buf = '\0'; ptr = dptr; while (*ptr) { for (ptr2 = ptr; *ptr2 && strncmp(ptr2, sepin, seplen); ptr2++); if (*ptr2) { *ptr2 = '\0'; ptr2 += seplen; } strcpy(tmp, ptr); dptr = MesgParse(argv[2],buf2); CHECKRETURN(dptr,"FILTER","arg 3"); if (truestr(buf2)) { if (*buf) strcat(buf, sepbuf); strcat(buf, ptr); } ptr = ptr2; if (!(--iter_limit)) ABORT_MPI("FILTER","Iteration limit exceeded"); } free_top_mvar(); return buf; }
const char * mfn_for(MFUNARGS) { int iter_limit = MAX_MFUN_LIST_LEN; char tmp[BUFFER_LEN]; char *ptr, *dptr; int v, i, start, end, incr; ptr = MesgParse(argv[0],argv[0]); CHECKRETURN(ptr,"FOR","arg 1 (varname)"); v = new_mvar(ptr, tmp); if (v == 1) ABORT_MPI("FOR","Variable name too long"); if (v == 2) ABORT_MPI("FOR","Too many variables already defined"); dptr = MesgParse(argv[1],argv[1]); CHECKRETURN(dptr,"FOR","arg 2 (start num)"); start = atoi(dptr); dptr = MesgParse(argv[2],argv[2]); CHECKRETURN(dptr,"FOR","arg 3 (end num)"); end = atoi(dptr); dptr = MesgParse(argv[3],argv[3]); CHECKRETURN(dptr,"FOR","arg 4 (increment)"); incr = atoi(dptr); *buf = '\0'; for (i = start; ((incr>=0 && i<=end) || (incr<0 && i>=end)); i += incr) { sprintf(tmp, "%d", i); dptr = MesgParse(argv[4],buf); CHECKRETURN(dptr,"FOR","arg 5 (repeated command)"); if (!(--iter_limit)) ABORT_MPI("FOR","Iteration limit exceeded"); } free_top_mvar(); return buf; }
char * do_parse_mesg_2(int descr, dbref player, dbref what, dbref perms, const char *inbuf, const char *abuf, char *outbuf, int outbuflen, int mesgtyp) { char howvar[BUFFER_LEN]; char cmdvar[BUFFER_LEN]; char argvar[BUFFER_LEN]; char tmparg[BUFFER_LEN]; char tmpcmd[BUFFER_LEN]; char *dptr; int mvarcnt = varc; int mfunccnt = funcc; int tmprec_cnt = mesg_rec_cnt; int tmpinst_cnt = mesg_instr_cnt; *outbuf = '\0'; if ((mesgtyp & MPI_NOHOW) == 0) { if (new_mvar("how", howvar)) { snprintf(howvar, sizeof(howvar), "%s Out of MPI variables.", abuf); notify_nolisten(player, howvar, 1); varc = mvarcnt; return outbuf; } strcpyn(howvar, sizeof(howvar), abuf); } if (new_mvar("cmd", cmdvar)) { snprintf(cmdvar, sizeof(cmdvar), "%s Out of MPI variables.", abuf); notify_nolisten(player, cmdvar, 1); varc = mvarcnt; return outbuf; } strcpyn(cmdvar, sizeof(cmdvar), match_cmdname); strcpyn(tmpcmd, sizeof(tmpcmd), match_cmdname); if (new_mvar("arg", argvar)) { snprintf(argvar, sizeof(argvar), "%s Out of MPI variables.", abuf); notify_nolisten(player, argvar, 1); varc = mvarcnt; return outbuf; } strcpyn(argvar, sizeof(argvar), match_args); strcpyn(tmparg, sizeof(tmparg), match_args); dptr = MesgParse(inbuf, outbuf, outbuflen); if (!dptr) { *outbuf = '\0'; } varc = mvarcnt; free_mfuncs(mfunccnt); mesg_rec_cnt = tmprec_cnt; mesg_instr_cnt = tmpinst_cnt; strcpyn(match_cmdname, sizeof(match_cmdname), tmpcmd); strcpyn(match_args, sizeof(match_args), tmparg); return outbuf; }
const char * mfn_lsort(MFUNARGS) { char *litem[MAX_MFUN_LIST_LEN]; char vbuf[BUFFER_LEN]; char vbuf2[BUFFER_LEN]; char *ptr, *ptr2, *tmp; int i, j, count; if (argc > 1 && argc < 4) ABORT_MPI("LSORT","Takes 1 or 4 arguments"); for (i = 0; i < MAX_MFUN_LIST_LEN; i++) litem[i] = NULL; ptr = MesgParse(argv[0],argv[0]); CHECKRETURN(ptr,"LSORT","arg 1"); if (argc > 1) { ptr2 = MesgParse(argv[1], argv[1]); CHECKRETURN(ptr2,"LSORT","arg 2"); j = new_mvar(ptr2, vbuf); if (j == 1) ABORT_MPI("LSORT","Variable name too long"); if (j == 2) ABORT_MPI("LSORT","Too many variables already defined"); ptr2 = MesgParse(argv[2],argv[2]); CHECKRETURN(ptr2,"LSORT","arg 3"); j = new_mvar(ptr2, vbuf2); if (j == 1) ABORT_MPI("LSORT","Variable name too long"); if (j == 2) ABORT_MPI("LSORT","Too many variables already defined"); } count = 0; while (*ptr) { for (ptr2 = ptr; *ptr2 && *ptr2 != '\r'; ptr2++); if (*ptr2 == '\r') *(ptr2++) = '\0'; litem[count++] = ptr; ptr = ptr2; if (count >= MAX_MFUN_LIST_LEN) ABORT_MPI("LSORT","Iteration limit exceeded"); } for (i = 0; i < count; i++) { for (j = i + 1; j < count; j++) { if (argc > 1) { strcpy(vbuf, litem[i]); strcpy(vbuf2, litem[j]); ptr = MesgParse(argv[3],buf); CHECKRETURN(ptr,"LSORT","arg 4"); if (truestr(buf)) { tmp = litem[i]; litem[i] = litem[j]; litem[j] = tmp; } } else { if (alphanum_compare(litem[i], litem[j]) > 0) { tmp = litem[i]; litem[i] = litem[j]; litem[j] = tmp; } } } } *buf = '\0'; for (i = 0; i < count; i++) { if (*buf) strcat(buf, "\r"); strcat(buf, litem[i]); } if (argc > 1) { free_top_mvar(); free_top_mvar(); } return buf; }
void prim_parsepropex(PRIM_PROTOTYPE) { struct inst* oper1 = NULL; /* prevents reentrancy issues! */ struct inst* oper2 = NULL; /* prevents reentrancy issues! */ struct inst* oper3 = NULL; /* prevents reentrancy issues! */ struct inst* oper4 = NULL; /* prevents reentrancy issues! */ stk_array* vars; const char* mpi; char* str = 0; array_iter idx; extern int varc; /* from msgparse.c */ int mvarcnt = 0; char* buffers = NULL; int novars; int hashow = 0; int i; int len; char tname[BUFFER_LEN]; char buf[BUFFER_LEN]; CHECKOP(4); oper4 = POP(); /* int:Private */ oper3 = POP(); /* dict:Vars */ oper2 = POP(); /* str:Prop */ oper1 = POP(); /* ref:Object */ if (mlev < 3) abort_interp("Mucker level 3 or greater required."); if (oper1->type != PROG_OBJECT) abort_interp("Non-object argument. (1)"); if (oper2->type != PROG_STRING) abort_interp("Non-string argument. (2)"); if (oper3->type != PROG_ARRAY) abort_interp("Non-array argument. (3)"); if (oper3->data.array && (oper3->data.array->type != ARRAY_DICTIONARY)) abort_interp("Dictionary array expected. (3)"); if (oper4->type != PROG_INTEGER) abort_interp("Non-integer argument. (4)"); if (!valid_object(oper1)) abort_interp("Invalid object. (1)"); if (!oper2->data.string) abort_interp("Empty string argument. (2)"); if ((oper4->data.number != 0) && (oper4->data.number != 1)) abort_interp("Integer of 0 or 1 expected. (4)"); CHECKREMOTE(oper1->data.objref); if (!prop_read_perms(ProgUID, oper1->data.objref, oper2->data.string->data, mlev)) abort_interp("Permission denied."); len = oper2->data.string->length; strcpyn(tname, sizeof(tname), oper2->data.string->data); while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) { tname[len] = '\0'; } mpi = get_property_class(oper1->data.objref, tname); vars = oper3->data.array; novars = array_count(vars); if (check_mvar_overflow(novars)) abort_interp("Out of MPI variables. (3)"); if (array_first(vars, &idx)) { do { array_data* val = array_getitem(vars, &idx); if (idx.type != PROG_STRING) { CLEAR(&idx); abort_interp("Only string keys supported. (3)"); } if (idx.data.string == NULL) { CLEAR(&idx); abort_interp("Empty string keys not supported. (3)"); } if (strlen(idx.data.string->data) > MAX_MFUN_NAME_LEN) { CLEAR(&idx); abort_interp("Key too long to be an MPI variable. (3)"); } switch(val->type) { case PROG_INTEGER: case PROG_FLOAT: case PROG_OBJECT: case PROG_STRING: case PROG_LOCK: break; default: CLEAR(&idx); abort_interp("Only integer, float, dbref, string and lock values supported. (3)"); break; } if (string_compare(idx.data.string->data, "how") == 0) hashow = 1; } while(array_next(vars, &idx)); } if (mpi && *mpi) { if (novars > 0) { mvarcnt = varc; if ((buffers = (char*)malloc(novars * BUFFER_LEN)) == NULL) abort_interp("Out of memory."); if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); array_data* val; val = array_getitem(vars, &idx); switch(val->type) { case PROG_INTEGER: snprintf(var_buf, BUFFER_LEN, "%i", val->data.number); break; case PROG_FLOAT: snprintf(var_buf, BUFFER_LEN, "%g", val->data.fnumber); break; case PROG_OBJECT: snprintf(var_buf, BUFFER_LEN, "#%i", val->data.objref); break; case PROG_STRING: strncpy(var_buf, DoNullInd(val->data.string), BUFFER_LEN); break; case PROG_LOCK: strncpy(var_buf, unparse_boolexp(ProgUID, val->data.lock, 1), BUFFER_LEN); break; default: var_buf[0] = '\0'; break; } var_buf[BUFFER_LEN - 1] = '\0'; new_mvar(idx.data.string->data, var_buf); } while(array_next(vars, &idx)); } } result = 0; if (oper4->data.number) result |= MPI_ISPRIVATE; if (Prop_Blessed(oper1->data.objref, oper2->data.string->data)) result |= MPI_ISBLESSED; if (hashow) result |= MPI_NOHOW; str = do_parse_mesg(fr->descr, player, oper1->data.objref, mpi, "(parsepropex)", buf, sizeof(buf), result); if (novars > 0) { if (array_first(vars, &idx)) { i = 0; do { char* var_buf = buffers + (i++ * BUFFER_LEN); struct inst temp; temp.type = PROG_STRING; temp.data.string = alloc_prog_string(var_buf); array_setitem(&vars, &idx, &temp); CLEAR(&temp); } while(array_next(vars, &idx)); } free(buffers); varc = mvarcnt; } } oper3->data.array = NULL; CLEAR(oper1); CLEAR(oper2); CLEAR(oper3); CLEAR(oper4); PushArrayRaw(vars); PushString(str); }