/* * aliases.c */ #include <ctype.h> #include <string.h> #include <malloc.h> #include <fcntl.h> #include <memory.h> #include "config.h" #include "player.h" #include "fix.h" #include "aliases.h" /* externs */ extern char *upper_from_saved(saved_player * sp); extern char *check_legal_entry(player *, char *, int); extern char *store_string(), *store_int(); extern char *get_string(), *get_int(); extern char *gstring_possessive(), *end_string(), *next_space(); extern player *find_player_global_quiet(char *), *find_player_global(char *); extern player *find_player_absolute_quiet(char *); extern saved_player *find_saved_player(char *); extern void log(char *, char *); extern void tell_player(player *, char *); extern char *number2string(int); extern char *full_name(player *); extern char *get_gender_string(player *); extern void save_player(player *); extern void pager(player *, char *, int); extern int global_tag(player *, char *); extern void cleanup_tag(player **, int); extern saved_player **saved_hash[]; int strnomatch(char *, char *, int); /* delete and entry from someones list */ void delete_entry_alias(saved_player * sp, alias * l) { alias *scan; if (!sp) return; scan = sp->alias_top; if (scan == l) { sp->alias_top = l->next; FREE(l); return; } while (scan) if (scan->next == l) { scan->next = l->next; FREE(l); return; } else scan = scan->next; log("error", "Tried to delete alias that wasn't there.\n"); } /* compress list */ void tmp_comp_alias(saved_player * sp) { char *oldstack; alias *l, *next; l = sp->alias_top; oldstack = stack; stack = store_int(stack, 0); while (l) { next = l->next; if (!l->cmd[0]) { log("error", "Bad list entry on compress .. auto deleted.\n"); delete_entry_alias(sp, l); } else { stack = store_string(stack, l->cmd); stack = store_string(stack, l->sub); } l = next; } store_int(oldstack, ((int) stack - (int) oldstack)); } /* */ void compress_alias(saved_player * sp) { char *oldstack; int length; alias *new, *l, *next; if (sp->system_flags & COMPRESSED_ALIAS) return; sp->system_flags |= COMPRESSED_ALIAS; oldstack = stack; tmp_comp_alias(sp); length = (int) stack - (int) oldstack; if (length == 4) { sp->alias_top = 0; stack = oldstack; return; } new = (alias *) MALLOC(length); memcpy(new, oldstack, length); l = sp->alias_top; while (l) { next = l->next; FREE(l); l = next; } sp->alias_top = new; stack = oldstack; } /* decompress list */ void decompress_alias(saved_player * sp) { alias *l; char *old, *end, *start; int length; if (!(sp->system_flags & COMPRESSED_ALIAS)) return; sp->system_flags &= ~COMPRESSED_ALIAS; old = (char *) sp->alias_top; start = old; if (!old) return; old = get_int(&length, old); end = old + length - 4; sp->alias_top = 0; while (old < end) { l = (alias *) MALLOC(sizeof(alias)); old = get_string(stack, old); strncpy(l->cmd, stack, MAX_NAME - 3); old = get_string(stack, old); strncpy(l->sub, stack, MAX_DESC - 3); l->next = sp->alias_top; sp->alias_top = l; } FREE(start); } /* save list */ void construct_alias_save(saved_player * sp) { int length; char *where; if (!(sp->system_flags & COMPRESSED_ALIAS) && (!find_player_absolute_quiet(sp->lower_name))) compress_alias(sp); if (sp->system_flags & COMPRESSED_ALIAS) { if (sp->alias_top) { where = (char *) sp->alias_top; (void) get_int(&length, where); memcpy(stack, where, length); stack += length; } else stack = store_int(stack, 4); } else tmp_comp_alias(sp); } /* retrieve list */ char *retrieve_alias_data(saved_player * sp, char *where) { int length; (void) get_int(&length, where); if (length == 4) sp->alias_top = 0; else { sp->system_flags |= COMPRESSED_ALIAS; sp->alias_top = (alias *) MALLOC(length); memcpy(sp->alias_top, where, length); } where += length; return where; } /* count list entries */ int count_alias(player * p) { alias *l; int count = 0; if (!p->saved) return 0; if (!p->saved->alias_top) return 0; for (l = p->saved->alias_top; l; l = l->next) count++; return count; } /* find list entry for a person */ alias *find_alias_entry(player * p, char *name) { alias *l; if (!p->saved) return 0; decompress_alias(p->saved); l = p->saved->alias_top; while (l) if (!strcasecmp(l->cmd, name)) return l; else l = l->next; return 0; } /* create a list entry */ alias *create_entry_alias(player * p, char *name) { alias *l; if (!p->saved) return 0; if ((count_alias(p)) >= (p->max_alias)) { tell_player(p, " Can't create new alias, " "because your alias list is full.\n"); return 0; } l = (alias *) MALLOC(sizeof(alias)); strncpy(l->cmd, name, MAX_NAME - 3); strncpy(l->sub, "", MAX_DESC - 3); l->next = p->saved->alias_top; p->saved->alias_top = l; return l; } /* view alias list */ void view_alias(player * p, char *str) { char *oldstack, li[]="Logon Script", lo[]="Logoff Script", re[]="Reconnect Script"; alias *l, *logon = 0, *logoff = 0, *recon = 0; int count; oldstack = stack; if (*str) { tell_player(p, " Format: lsa (lists all aliases)\n"); return; } if (!p->saved) { tell_player(p, " You have no alias list to view.\n"); return; } count = count_alias(p); sprintf(stack, " You are using %d of your maximum %d aliases.\n", count, p->max_alias); stack = strchr(stack, 0); if (count) { for (l = p->saved->alias_top; l; l = l->next) { if (!strcmp(l->cmd, "_logon")) logon = l; else if (!strcmp(l->cmd, "_logoff")) logoff = l; else if (!strcmp(l->cmd, "_recon")) recon = l; else { sprintf(stack, "^B%-20s^N = %s", l->cmd, l->sub); stack = strchr(stack, 0); *stack++ = '\n'; } } if (logon || logoff || recon) { strcpy(stack, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"); stack = strchr(stack, 0); if (logon) { sprintf(stack, "^B%-20s^N = %s", li, logon->sub); stack = strchr(stack, 0); *stack++ = '\n'; } if (logoff) { sprintf(stack, "^B%-20s^N = %s", lo, logoff->sub); stack = strchr(stack, 0); *stack++ = '\n'; } if (recon) { sprintf(stack, "^B%-20s^N = %s", re, recon->sub); stack = strchr(stack, 0); *stack++ = '\n'; } } } *stack++ = 0; pager(p, oldstack, 0); stack = oldstack; } /* undefine a macro? */ void undefine_alias(player * p, char *str) { char *oldstack, *text, msg[50]; int count = 0; alias *l; oldstack = stack; if (!p->saved) { tell_player(p, " You do not have an alias list to alter, " "since you are not saved\n"); return; } if (!*str) { tell_player(p, " Format: undefine <alias to undefine>\n"); return; } { l = find_alias_entry(p, str); if (!l) { text = stack; sprintf(stack, " Can't find any alias list entry for '%s'.\n", str); stack = end_string(stack); tell_player(p, text); } else { count++; sprintf(msg, " Entry removed for '%s'\n", l->cmd); tell_player(p, msg); delete_entry_alias(p->saved, l); } } stack = oldstack; if (!count) tell_player(p, " No entries removed.\n"); else { sprintf(stack, " Deleted alias.\n"); stack = end_string(stack); tell_player(p, oldstack); } stack = oldstack; } /* define an alias -- woowoo */ void define_alias(player * p, char *str) { char *doh, *oldstack, *scanned; int count = 0; alias *l; if (!p->saved) { tell_player(p, " You can't alias because you have no save file.\n"); return; } oldstack = stack; doh = next_space(str); if (!*doh) { tell_player(p, " Format: define <alias> <command to do instead>\n"); return; } *doh++ = 0; /* strip extra spaces from str */ scanned = str; while (*str && !(isspace(*str))) *str++; *str++ = 0; str = scanned; l = find_alias_entry(p, str); if (!l) l = create_entry_alias(p, str); if (l) { count++; strncpy(l->sub, doh, MAX_DESC - 3); } if (count) tell_player(p, " Alias defined.\n"); else tell_player(p, " Error - could not create alias.\n"); } char *do_alias_match(player * p, char *str) { char *t; alias *scan; int g; if (!p->saved) return "\n"; scan = p->saved->alias_top; while (scan) { g = 1; if (strnomatch(scan->cmd, str, 0)) g=0; if (g) { while (*str && *str != ' ') str++; while (*str && isspace(*str)) str++; return str; } scan = scan->next; } return "\n"; } alias *get_alias(player * p, char *str) { char *t; alias *scan; int g; if (!p->saved) return 0; scan = p->saved->alias_top; while (scan) { g = 1; if (strnomatch(scan->cmd, str, 0)) g=0; if (g) { return scan; } scan = scan->next; } return 0; } char *splice_argument(player *p, char *str, char *arg, int conti) { static char BUFFER[1000], arghold[1000], strhold[1000], num[2]; static char RARG[10][100]; static int b, a, s; int no, word, r1, r2; if (!(conti)) { /* reset variables */ s=0; a=0; if (*arg) strncpy(arghold, arg, 999); else strncpy(arghold, "", 999); strncpy(strhold, str, 999); num[0] = 0; num[1] = 0; } for (b=0; b<1000; b++) BUFFER[b] = 0; b=0; while (1) { if (!strhold[s]) { /* true end of function */ BUFFER[b++] = 0; return BUFFER; } else if (strhold[s] != '%') { BUFFER[b++] = strhold[s++]; } else { if (strhold[s+1] == ';') { BUFFER[b++] = 0; s+=2; return BUFFER; } else if (strhold[s+1] == '%') { BUFFER[b++] = '%'; s+=2; } else if (strhold[s+1] == '0') { s+=2; a=0; while (arghold[a]) BUFFER[b++] = arghold[a++]; } else if (strhold[s+1] == '-') { s+=3; num[0] = strhold[s-1]; num[1] = 0; no = atoi(num); a=0; for (word=0; word != no; a++) { if (!arghold[a]) { word=no; } else if (isspace(arghold[a])) word++; } while (arghold[a]) BUFFER[b++] = arghold[a++]; } else if (isdigit(strhold[s+1])) { s+=2; num[0] = strhold[s-1]; num[1] = 0; no=atoi(num); a=0; for (word=1; word != no; a++) { if (!arghold[a]) { word=no; } else if (isspace(arghold[a])) word++; } while (arghold[a] && !(isspace(arghold[a]))) BUFFER[b++] = arghold[a++]; } else if (strhold[s+1] == '{') { /* first, clear all the old rargs */ for (r1=0; r1 < 10; r1++) for (r2=0; r2 < 100; r2++) RARG[r1][r2] = 0; /* now, fill in the data into RARG */ r1 = 0; r2 = 0; s+=2; while (strhold[s] != '}') { if (r1 < 10 && r2 < 99) { if (strhold[s] == '@') { RARG[r1++][r2] = 0; r2 = 0; } else RARG[r1][r2++] = strhold[s]; } else if (r1 < 10) { RARG[r1++][r2] = 0; r2 = 0; } s++; } /* this should ALWAYS (finger crossed) be in range */ RARG[r1][r2] = 0; /* now we have args -- choose one at random */ s++; /* get the s to the space after the %{...} */ r2 = (rand() % (r1 + 1)); r1 = 0; while (RARG[r2][r1]) { BUFFER[b++] = RARG[r2][r1++]; } } else s+=2; } } return ""; } int strnomatch(char *str1, char *str2, int unanal) { char *s1p, *s2p; s1p = str1; s2p = str2; for (;*s1p;s1p++,s2p++) { if (unanal && *s1p != *s2p) return 1; else if (tolower(*s1p) != tolower(*s2p)) return 1; } if (!unanal && *s2p && (!isspace(*s2p))) return 1; return 0; } /* view someone else's alias list, if you are Admin */ void view_others_aliases(player * p, char *str) { char *oldstack, li[] = "Login", lo[]="Logout", re[] = "Reconnect"; int count; player *p2, dummy; alias *l, *logon = 0, *logoff = 0, *recon = 0; oldstack = stack; memset(&dummy, 0, sizeof(player)); if (!*str) { tell_player(p, " Format: val <player>\n"); return; } lower_case(str); p2 = find_player_global_quiet(str); if (!p2) { strcpy(dummy.lower_name, str); dummy.fd = p->fd; if (!load_player(&dummy)) { tell_player(p, " That person does not exist!\n"); return; } p2=&dummy; } if (!p2->saved) { tell_player(p, " That person has no alias list to view.\n"); return; } count = count_alias(p2); sprintf(stack, "%s is using %d of %s maximum %d alias list entries.\n", p2->name, count, their_player(p2), p2->max_alias); stack = strchr(stack, 0); if (count) { for (l = p2->saved->alias_top; l; l = l->next) { if (!strcmp(l->cmd, "_logon")) logon = l; else if (!strcmp(l->cmd, "_logoff")) logoff = l; else if (!strcmp(l->cmd, "_recon")) recon = l; else { sprintf(stack, "^B%-20s^N - %s", l->cmd, l->sub); stack = strchr(stack, 0); *stack++ = '\n'; } } if (logon || logoff || recon) { strcpy(stack, "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"); stack = strchr(stack, 0); if (logon) { sprintf(stack, "^B%-20s^N = %s", li, logon->sub); stack = strchr(stack, 0); *stack++ = '\n'; } if (logoff) { sprintf(stack, "^B%-20s^N = %s", lo, logoff->sub); stack = strchr(stack, 0); *stack++ = '\n'; } if (recon) { sprintf(stack, "^B%-20s^N = %s", re, recon->sub); stack = strchr(stack, 0); *stack++ = '\n'; } } } *stack++ = 0; pager(p, oldstack, 0); stack = oldstack; } void define_logon_macro(player * p, char *str) { char *oldstack; if (!*str) { undefine_alias(p, "_logon"); return; } oldstack = stack; sprintf(stack, "_logon %s", str); stack = end_string(stack); define_alias(p, oldstack); stack = oldstack; } void define_logoff_macro(player * p, char *str) { char *oldstack; if (!*str) { undefine_alias(p, "_logoff"); return; } oldstack = stack; sprintf(stack, "_logoff %s", str); stack = end_string(stack); define_alias(p, oldstack); stack = oldstack; } void define_recon_macro(player * p, char *str) { char *oldstack; if (!*str) { undefine_alias(p, "_recon"); return; } oldstack = stack; sprintf(stack, "_recon %s", str); stack = end_string(stack); define_alias(p, oldstack); stack = oldstack; } void library_list(player * p, char *str) { char *oldstack; int i = 0; oldstack = stack; strcpy(stack, " Listing all aliases currently in the library.\n"); stack = strchr(stack, 0); strcpy(stack, " Please submit your favorite aliases that you'd like everyone to share by internal mail to traP.\n"); stack = strchr(stack, 0); while (library[i].command) { if (!(library[i].privs) || p->residency & PSU) { sprintf(stack, "%s, ", library[i].command); stack = strchr(stack, 0); } i++; } stack-=2; *stack++ = '\n'; *stack++ = 0; tell_player(p, oldstack); stack = oldstack; } alias_library get_lib_alias(char *str) { int i = 0; while (library[i].command) { if (!strcasecmp(str, library[i].command)) return library[i]; i++; } return no_library_here; } void library_copy(player * p, char *str) { char *oldstack, *new_alias_name; alias_library to_be_copied; if (!*str) { tell_player(p, " Format: libcopy <library alias> [<Your name for alias>]\n"); return; } new_alias_name = next_space(str); if (*new_alias_name) *new_alias_name++ = 0; to_be_copied = get_lib_alias(str); if (!to_be_copied.command || (to_be_copied.privs && !(p->residency & PSU))) { tell_player(p, " That alias not found in the library.\n"); return; } else { oldstack = stack; if (*new_alias_name) sprintf(stack, "%s %s", new_alias_name, to_be_copied.alias_string); else sprintf(stack, "%s %s", to_be_copied.command, to_be_copied.alias_string); stack = end_string(stack); define_alias(p, oldstack); stack = oldstack; } } void library_examine(player * p, char *str) { alias_library see_this; char *oldstack; if (!*str) { tell_player(p, " Format: Libexam <library alias to examine>\n"); return; } see_this = get_lib_alias(str); if (!see_this.command || (see_this.privs && !(p->residency & PSU))) { tell_player(p, " Couldn't find that alias in the library.\n"); return; } oldstack = stack; sprintf(stack, "Command: %s\nDoes : %s\nUsage : %s\nAuthor : %s\n", see_this.command, see_this.alias_string, see_this.description, see_this.author); stack = end_string(stack); tell_player(p, oldstack); stack = oldstack; } /* well, we learned that aliases ain't perfect neither */ void blank_all_aliases(player * p, char *str) { if (!p->saved) { tell_player(p, "You can't -- you have no alias list anyway"); return; } p->saved->alias_top = 0; tell_player(p, "Aliases deleted.\n"); }