/* utils.c */ #include "copyright.h" #include "config.h" #include <stdio.h> #ifdef STRING_H #include <string.h> #else #include <strings.h> #endif /* STRING_H */ #include <ctype.h> #include <sys/time.h> #ifdef STDDEF_H #include <stddef.h> #else /* STDDEF_H */ #define size_t unsigned #endif /* STDDEF_H */ #include "teeny.h" /* * Some generic utility functions for TeenyMUD */ /* * Write a timestamp on an object. In minutes since Jan 1 1970 */ #ifdef TIMESTAMPS void stamp(obj) { struct timeval foo; (void) gettimeofday(&foo, (struct timezone *) 0); if (set_int_elt(obj, TIMESTAMP, (int) (foo.tv_sec / 60)) == -1) { warning("timestamp", "failed write to object"); } } #endif /* * Manufactures a new player and returns the object number, one doesn't exist * already. * */ int create_player(p, code) char *p; int code; { char *name, *pwd; int player; int list; char *work; if (parse_name_pwd(p, &name, &pwd) == -1) return (-1); if (!ok_player_name(name)) return (-1); work = (char *) ty_malloc(strlen(name) + strlen(pwd) + 2, "create_player"); strcpy(work, name); work[strlen(name)] = ' '; strcpy(work + strlen(name) + 1, pwd); /* Create a player in object number 0 */ player = create_obj(TYP_PLAYER); if (set_str_elt(player, NAME, work) == -1) goto createboom; if (code == -1) { if (get_int_elt(STARTING_LOC, CONTENTS, &list) == -1) goto createboom; if (set_int_elt(player, LOC, STARTING_LOC) == -1) goto createboom; if (set_int_elt(STARTING_LOC, CONTENTS, player) == -1) goto createboom; } else { if (get_int_elt(code, CONTENTS, &list) == -1) goto createboom; if (set_int_elt(player, LOC, code) == -1) goto createboom; if (set_int_elt(code, CONTENTS, player) == -1) goto createboom; } if (set_int_elt(player, NEXT, list) == -1) goto createboom; if (set_int_elt(player, HOME, STARTING_LOC) == -1) goto createboom; if (set_int_elt(player, OWNER, player) == -1) goto createboom; if (code == -1) { int loc; if (get_int_elt(player, LOC, &loc) == -1) goto createboom; animate(player); if (!isdark(player) && !isdark(loc)) do_pose(player, "has connected."); } #ifdef TIMESTAMPS stamp(player); #endif ty_free(work); return (player); createboom: ty_free(work); destroy_obj(player); return (-1); } /* * Connects a player, if it exists and the password matches. Returns -1 if no * dice. * */ int connect_player(p) char *p; { char *name, *pwd; char *realname; int player; if (parse_name_pwd(p, &name, &pwd) == -1) return (-1); player = match_player(name); if (player == -1) { return (-1); } /* Check the password */ if (get_str_elt(player, NAME, &realname) == -1) { warning("connect_player", "could not reference name"); return (-1); } /* Assume no leading whitespace */ while (!isspace(*realname) && *realname) realname++; while (isspace(*realname) && *realname) realname++; if (*realname == '\0') return (-1); if (strcmp(realname, pwd) == 0) { int loc; #ifdef TIMESTAMPS stamp(player); #endif if (get_int_elt(player, LOC, &loc) == -1) { warning("connect_player", "could not ref player location"); return (-1); } if (!isdark(player) && !isdark(loc)) do_pose(player, "has connected."); animate(player); return (player); } return (-1); } void disconnect_player(player) int player; { int loc; if (get_int_elt(player, LOC, &loc) == -1) { warning("disconnect_player", "could not ref player loc"); return; } if (!isdark(player) && !isdark(loc)) do_pose(player, "has disconnected."); } /* * Hack name/pwd pair up. * */ int parse_name_pwd(p, name, pwd) char *p; char **name, **pwd; { while (isspace(*p) && *p) p++; if (*p == '\0') return (-1); *name = p; while (!isspace(*p) && *p) p++; if (*p == '\0') return (-1); *p++ = '\0'; while (isspace(*p) && *p) p++; if (*p == '\0') return (-1); *pwd = p; /* Assume no trailing whitespace. */ return (0); } /* * Reliable memory allocation. */ char * ty_malloc(n, util) int n; char *util; /* Identifies the calling routine */ { char *p; extern char *malloc(); if ((p = (char *) malloc((size_t) n)) == NULL) { fatal(util, "memory allocation failed"); } return (p); } /* * Reliable free(), which does NULL OK. */ void ty_free(p) char *p; { if (p == NULL) { return; /* Ok */ } free(p); } /* * Converts ints to strings. * */ char * ty_itoa(p, i) char *p; int i; { char *ty_itoa_prim(); if (i < 0) { i = -i; *p++ = '-'; } else if (i == 0) { *p++ = '0'; return (p); } return (ty_itoa_prim(p, i)); } /* recursively does it to it. Hee! Russ would love me. */ char * ty_itoa_prim(p, i) char *p; int i; { if (i == 0) { return (p); } else { p = ty_itoa_prim(p, i / 10); *p++ = (char) (i % 10) + '0'; return (p); } } void parse_type(str, ret) char *str; int *ret; { if (stringprefix(str, "player")) { *ret = TYP_PLAYER; } else if (stringprefix(str, "room")) { *ret = TYP_ROOM; } else if (stringprefix(str, "thing") || stringprefix(str, "object")) { *ret = TYP_THING; } else if (stringprefix(str, "exit")) { *ret = TYP_EXIT; } /* else leave ret alone */ } /* an idea from TinyMUD that has been a long time in coming.. */ int ok_name(name) char *name; { return (name && *name && *name != '*' && *name != '#' && *name != '!' && !index(name, '=') && !index(name, '&') && !index(name, '|') #ifdef ILLEGAL_NAMES && strcasecmp(name, "A") && strcasecmp(name, "An") && strcasecmp(name, "The") && strcasecmp(name, "You") && strcasecmp(name, "Your") && strcasecmp(name, "Going") && strcasecmp(name, "Huh?") && strcasecmp(name, "[") #endif /* ILLEGAL_NAMES */ && strcasecmp(name, "me") && strcasecmp(name, "home") && strcasecmp(name, "here")); } int ok_player_name(name) char *name; { if (!ok_name(name) || (strlen(name) > 16) || (match_player(name) != -1) /*|| index(name, '=') || index(name, '&') || index(name, '|')*/) return (0); else return (1); } int ok_exit_name(name) char *name; { char *p, *q, *buf; if(!ok_name(name)) return (0); buf = (char *)ty_malloc(strlen(name) + 1, "ok_exit_name"); (void)strcpy(buf, name); /* we have to check each sub string... */ q = buf; while(q && *q){ for(p = q; *p && *p != ';'; p++); if(*p) *p++ = 0; if(!ok_name(q)){ ty_free((char *)buf); return (0); } q = p; } ty_free((char *)buf); return(1); }