#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "db.h" #include "externs.h" #include "paste.h" #include "powers.h" PASTE *paste_stack = NULL; PASTE *find_paste(DDATA *des) { PASTE *p; for(p = paste_stack;p;p = p->next) if(p->des == des) return(p); return(NULL); } bool is_pasting(DDATA *des) { return((des->mode == MODE_PASTE)); } static void add_to_stack(DDATA *des, OBJ *who, ATTR *attr, COM *channel, PROG *program) { PASTE *new; new = (PASTE *)stack_alloc(sizeof(PASTE), 1, 0); new->next = paste_stack; paste_stack = new; new->des = des; new->who = who; new->paste = NULL; new->attr = attr; new->channel = channel; new->program = program; } void remove_paste(DDATA *des) { PASTE *p, *pprev = NULL; struct pastey *q, *qnext; for(p = paste_stack;p;p = p->next) { if(p->des == des) break; pprev = p; } if(!p) return; for(q = p->paste;q;q = qnext) { qnext = q->next; stack_free(q->str); stack_free(q); } if(!pprev) paste_stack = p->next; else pprev->next = p->next; if(p == paste_stack) paste_stack = NULL; stack_free(p); des->mode = MODE_NORMAL; } void do_paste(DDATA *des, char *arg1, char *arg2) { OBJ *who = NULL; ATTR *attr = NULL; COM *channel = NULL; PROG *program = NULL; char *p; if(is_pasting(des)) { notify(des->player, "Clearing old paste, starting fresh."); remove_paste(des); } if(*arg1) { /* See if they're pasting to a channel or program */ if(*arg2) { if(string_prefix("channel", arg1)) { channel = find_channel(des->player, arg2); if(!channel || !is_on_channel(des->player, channel, 1)) { notify(des->player, tprintf("You're not on channel \"%s\"!", arg2)); return; } } else if(string_prefix("program", arg1)) { if(!(p = strchr(arg2, ','))) { notify(des->player, "Illegal syntax!"); return; } *p++ = '\0'; if(!(who = match_object(des->player, arg2, NOTYPE))) { notify(des->player, no_match(arg2)); return; } if(!(program = find_prog(who, p))) { add_new_prog(des->player, who, p); if(!(program = find_prog(who, p))) return; } } else { notify(des->player, "Illegal syntax!"); return; } } else { /* Check if they're pasting to an attribute */ if((p = strchr(arg1, '/'))) *p++ = '\0'; if(!(who = match_object(des->player, arg1, NOTYPE))) { notify(des->player, no_match(arg1)); return; } if(!could_doit(des->player, who, "LPAGE")) { notify(des->player, "Sorry, that player is page-locked against you."); return; } if(p) { if(!controls(des->player, who, POW_MODIFY) && p) { notify(des->player, perm_denied()); return; } if(!(attr = find_attr(p))) { notify(des->player, "No match."); return; } } } } add_to_stack(des, who, attr, channel, program); notify(des->player, "Enter lines to be pasted. End input with a period (.) or type '@pasteabort'."); /* Process their output now or they'll never know they're in paste mode */ /* because their output is held in paste mode */ process_output(des); des->mode = MODE_PASTE; } static void do_end_paste(DDATA *des) { PASTE *p; char *s; struct pastey *q; char buf[1024]; int linenum; if(!(p = find_paste(des))) return; des->mode = MODE_NORMAL; if(p->attr) { if(!p->paste) atr_clr_a(p->who, p->attr); else atr_add_a(p->who, p->attr, p->paste->str); notify(des->player, tprintf("%s - Set.", name(p->who))); return; } if(p->channel) { com_send(p->channel->name, NULL, tprintf("|+W|----- |+B|Begin @paste text from %s |+W|-----", name(des->player))); for(q = p->paste;q;q = q->next) com_send(p->channel->name, NULL, q->str); com_send(p->channel->name, NULL, tprintf("|+W|----- |+B|End @paste text from %s |+W|-----", name(des->player))); return; } if(p->program) { for(q = p->paste;q;q = q->next) { if(is_running(p->program)) { notify(des->player, "You may not modify a program while it is running."); return; } for(s = q->str;isdigit(*s);s++); /* Whole loop */ if(!(s-q->str)) { if(!(linenum = next_line_num(p->program))) { notify(des->player, "Error! Next line number would exceed 65535."); return; } } else { strncpy(buf, q->str, s-q->str); *(buf+(s-q->str)) = '\0'; linenum = atoi(buf); if(linenum < 1 || linenum > 65535) { notify(des->player, "Valid line numbers are 1 through 65535."); return; } if(*s) s++; } if(!*s) del_prog_line(p->program, linenum); else add_prog_line(p->program, linenum, s); } notify(des->player, "Program modified."); return; } sprintf(buf, "|+W|----- |+B|Begin @paste text from %s |+W|-----", name(des->player)); if(!(p->who)) notify_in(des->player->location, NULL, buf); else notify(p->who, buf); for(q = p->paste;q;q = q->next) { if(!(p->who)) notify_in(des->player->location, NULL, q->str); else notify(p->who, q->str); } sprintf(buf, "|+W|----- |+B|End @paste text from %s |+W|-----", name(des->player)); if(!(p->who)) notify_in(des->player->location, NULL, buf); else { notify(p->who, buf); notify(des->player, tprintf("@paste text sent to %s.", unparse_object(des->player, p->who))); } } void add_more_paste(DDATA *des, char *str) { PASTE *p; struct pastey *q, *qnew, *qprev = NULL; if(!strcmp(str, ".")) { do_end_paste(des); remove_paste(des); return; } if(!string_compare("@pasteabort", str)) { remove_paste(des); notify(des->player, "@paste aborted."); return; } if(!(p = find_paste(des))) return; if(p->attr) { if(!p->paste) { p->paste = (struct pastey *)stack_alloc(sizeof(struct pastey), 1, 0); SET(p->paste->str, str); p->paste->next = NULL; } else { p->paste->str = (char *)stack_realloc(p->paste->str, strlen(p->paste->str)+strlen(str)+1); strcpy(p->paste->str+strlen(p->paste->str), str); } return; } qnew = (struct pastey *)stack_alloc(sizeof(struct pastey), 1, 0); SET(qnew->str, str); qnew->next = NULL; for(q = p->paste;q;q = q->next) qprev = q; if(!qprev) p->paste = qnew; else qprev->next = qnew; } void do_pastestats(OBJ *player, char *arg) { PASTE *p; struct pastey *q; int i, size; char buf[1024]; int num_pastes = 0; if(!power(player, POW_MISC)) { notify(player, perm_denied()); return; } if(!paste_stack) { notify(player, "There are no @paste texts being created."); return; } if(!*arg) { for(p = paste_stack;p;p = p->next) { size = 0; for(q = p->paste;q;q = q->next) size += strlen(q->str)+1; if(!(p->who)) strcpy(buf, "NOBODY"); else { strcpy(buf, name(p->who)); if(p->attr) sprintf(buf+strlen(buf), "/%s", p->attr->name); if(p->channel) sprintf(buf+strlen(buf), "CHANNEL %s", p->channel->name); if(p->program) sprintf(buf+strlen(buf), "PROGRAM %s", p->program->name); } notify(player, tprintf("%d: %s -> %s: %d bytes", ++num_pastes, name(p->des->player), buf, size)); } return; } for(p = paste_stack;p;p = p->next) num_pastes++; if(atoi(arg) < 1 || atoi(arg) > num_pastes) { notify(player, tprintf("Valid @pastes: 1 - %d", num_pastes)); return; } i = 0; for(p = paste_stack;p;p = p->next) { if(++i == atoi(arg)) break; } if(!p) /* Shouldn't happen */ return; size = 0; for(q = p->paste;q;q = q->next) size += strlen(q->str)+1; if(!(p->who)) strcpy(buf, "NOBODY"); else { strcpy(buf, name(p->who)); if(p->attr) sprintf(buf+strlen(buf), "/%s", p->attr->name); if(p->channel) sprintf(buf+strlen(buf), "CHANNEL %s", p->channel->name); if(p->program) sprintf(buf+strlen(buf), "PROGRAM %s", p->program->name); } notify(player, buf); notify(player, "|+B|------ |+W|BEGIN |+B|------"); for(q = p->paste;q;q = q->next) notify(player, q->str); notify(player, "|+B|------ |+W|END |+B|------"); }