/* prometheus's new editor */ #include <stdlib.h> #include "edit.h" #include "sflags.h" #include "pflags.h" /* This is the command to edit files in the data directory */ void editcom() { char path[256]; if (!ptstflg(mynum, PFL_EDITOR)) bprintf("You can't use the editor!\n"); else { if(brkword() != 1 && wordbuf != NULL && wordbuf[0] != '\0') { sprintf(path, "%s/%s", EDIT_PATH, wordbuf); start_editor("You may use game commands with *command.", "&+W[&+BC-Edit %.3d&+W] &N", path, path, False, TYPE_WRITE); } else bprintf("Edit what?\n"); } } /* This is the command to start the editor. * message...... displayed on startup * prompt....... a prompt with %d somewhere in it for the line number * infile....... file to load, NULL if none * outfile...... output file to write to * quote........ should a ">" be placed on each line of infile? * type......... type of output file, one of: * TYPE_MAIL, TYPE_APPEND, TYPE_CREATE, TYPE_DESC, TYPE_WRITE */ void start_editor(char *message, char *prompt, char *infile, char *outfile, Boolean quote, int type){ cur_player->edit_inp_handler = phandler(mynum); bprintf(E_TITLE); bprintf("%s\n", message); strcpy(eprompt, prompt); edit_status = NORMAL_MODE; cur_player->edit_mode = type; strcpy(cur_player->edit_outfile, outfile); curr_line = 1; if (infile != NULL) { load_buff(infile, quote); if (type == TYPE_MAIL || type == TYPE_DESC) view_text(); } show_prompt(); replace_input_handler(edit1); } void queue_line(int linenum) { for (txt_curr = txt_start; linenum > 0 && txt_curr->next != NULL; txt_curr = txt_curr->next, linenum--); } /* should be switched over to unix IO */ void load_buff(char *infile, Boolean quote) { FILE *fptr; char buff[MAX_COM_LEN]; numlines = 0; txt_curr = txt_start = NULL; if ((fptr = FOPEN(infile, "r")) == NULL) return; else { if (quote) while (1) { fgets(&buff[2], MAX_COM_LEN - 3, fptr); if (feof(fptr)) break; else { buff[0] = '>'; buff[1] = ' '; new_line(buff); } } else while (1) { fgets(buff, MAX_COM_LEN - 1, fptr); if (feof(fptr)) break; else new_line(buff); } FCLOSE(fptr); if (quote) bprintf(QUOTE_MSG, numlines); else if (cur_player->edit_mode == TYPE_DESC) bprintf(DESC_MSG, numlines); else if (plev(mynum) < LVL_DEMI) { if (numlines) bprintf(READ_MSG, numlines, (numlines > 1) ? "s" : ""); else bprintf(READ_MSG2); } else bprintf(GOD_READ_MSG, numlines, (numlines > 1) ? "s" : "", infile); } } void save_buff(char *outfile, int type) { int fd; int open_flags = 0; Text_Ptr txt_ptr; if (numlines) bprintf(SAVE_MSG, numlines, (numlines > 1) ? "s" : "" ); else bprintf(SAVE_MSG2); switch (type) { case TYPE_APPEND: open_flags = O_WRONLY | O_APPEND | O_CREAT; break; case TYPE_CREATE: case TYPE_MAIL: case TYPE_DESC: open_flags = O_WRONLY | O_CREAT | O_TRUNC; break; case TYPE_WRITE: open_flags = O_WRONLY | O_CREAT; break; } if ((fd = OPEN(outfile, open_flags, 0664)) != -1) { if (type == TYPE_MAIL) store_header(fd); for (txt_ptr = txt_start; txt_ptr != NULL; txt_ptr = txt_ptr->next) write(fd, txt_ptr->line, strlen(txt_ptr->line)); if (type == TYPE_MAIL) write(fd, "***\n", 4); CLOSE(fd); } else { bprintf("Error saving file.\n"); mudlog("ERROR: save_buff"); } } void free_list() { Text_Ptr txt_ptr; Text_Ptr tmpptr = NULL; for (txt_ptr = txt_start; txt_ptr != NULL; txt_ptr = txt_ptr->next) { FREE(tmpptr); tmpptr = txt_ptr; } FREE(tmpptr); txt_curr = txt_start = NULL; numlines = 0; curr_line = 1; } void new_line(char *input) { Text_Ptr newline; int j; Boolean newline_found = False; newline = NEW(Text_Line, 1); for (j = 0 ; input[j] != '\0' ; j++) { newline->line[j] = input[j]; if (input[j] == '\n') newline_found = True; } if (newline_found) /* restore null */ newline->line[j] = '\0'; else { newline->line[j] = '\n'; newline->line[j + 1] = '\0'; } newline->next = NULL; if (numlines == 0) /* first line of text */ txt_start = txt_curr = newline; else { txt_curr->next = newline; txt_curr = txt_curr->next; } numlines++; curr_line++; } void add_lines(int linenum) { if (linenum > 0) { bprintf(ADD_MSG, linenum); linenum--; } else bprintf(ADD_MSG2); queue_line(linenum); if (txt_curr != NULL) cur_player->tmp_ptr = txt_curr->next; else cur_player->tmp_ptr = NULL; edit_status = ADD_MODE; edit1(NULL); } void delete_line(int linenum) { Text_Ptr tmpptr; if ((linenum - 1) == 0) { tmpptr = txt_start; txt_start = txt_start->next; FREE(tmpptr); } else { queue_line(linenum - 2); tmpptr = txt_curr->next; txt_curr->next = txt_curr->next->next; FREE(tmpptr); } numlines--; } void view_text (void) { int j = 1; Text_Ptr txt_ptr; bprintf( "\n" ); for (txt_ptr = txt_start ; txt_ptr != NULL ; txt_ptr = txt_ptr->next) bprintf("&+B[&+M%.3d&+B]&+W: %s", j++, txt_ptr->line); bprintf("\n"); } /* return difference of 2 input numbers */ int getnum (char *str, int *num) { char *ptr; int num1, num2; for (ptr = str ; !isdigit(*ptr) ; ptr++) { if (*ptr == '\0') { bprintf("This command must be followed by a number.\n"); return -1; } } num1 = atoi(ptr); if ((ptr = strchr(str, '-')) != NULL) { if (num1 == 0 || (num2 = atoi(ptr + 1)) == 0) { bprintf("To use this feature, type a range. Ex: D 1-5\n"); return -1; } else { if (num1 > numlines || num2 > numlines || num1 < 1 || num2 < 1 || ((num2 - num1) < 0)) { bprintf("Number out of range.\n"); return -1; } else { *num = num1; return(num2 - num1 + 1); } } } else { *num = num1; if (*num > numlines || *num < 1) { bprintf("Number out of range.\n"); return -1; } else return 1; } } void show_prompt() { static char edit_prompt[80]; sprintf(edit_prompt, eprompt, curr_line); strcpy(cur_player->cprompt, edit_prompt); } void editor_help(void) { bprintf("\nHelp for the &+BCDirt editor commands:\n\n" "&+RE&+WX&+Rit&N................... Save the buffer, then exit\n" "&+WS&+Mave&N................... Save the buffer\n" "&+WC&+Yancel&N................. Stop editing this buffer\n" "&+WNew&N.................... Start editing from srcatch\n" "&+WD&+Celete [Line#]&N.. ...... *Delete a line of text\n" "&+WD&+Belete [Line# - Line#].&N *Delete multiple lines of text\n" "&+WI&+Gnsert [Line#]&N......... *Insert text after [line #]\n" "&+W*&+y[command]&N............. Run a mud command in editor\n" "&+W=&+y[command&N.............. Run a menu command from edit mode\n" "&+y[return]&N............... View current buffer\n\n" "&+Y*Note: Commands marked with an asterisk will cause lines to be " "re-numbered\n&+YAs this may cause some confusion, it is probably " "best to issue the command,\nthen type &+y[RETURN]&+Y to view the " "buffer.\n"); } void clean_up() { if (cur_player->inmailer) { strcpy(cur_player->cprompt, MAILPROMPT); bprintf(RETURN_MSG); } else strcpy(cur_player->cprompt, (char *) build_prompt(mynum)); replace_input_handler(cur_player->edit_inp_handler); } /* not working yet */ int cancel_buff(char *input) { if (input == NULL) { bprintf(CANCEL_MSG); replace_input_handler( (void *) cancel_buff); } else if (*input == 'Y' || *input == 'y') { bprintf(CANCELED); } else if (*input == 'N' || *input == 'n') { bprintf("Cancel aborted.\n"); edit1(NULL); return 0; } else replace_input_handler((void *) cancel_buff); return 0; } void send_mail() { int sendto, tmp_mynum, fd1, fd2; char tmp_path[256]; char mail_path[256]; char buff[MAX_COM_LEN]; PERSONA p; int numread; /* copy tmp file to player's mailbox */ /* Internet email */ #ifdef INTERNET_EMAIL if( is_internet_email( cur_player->work_msg->mailto ) ) { char sendmail[200]; char title[TITLE_LEN]; char type = 'w'; FILE *fptr; strip_color( title, make_title( ptitle(mynum), pname(mynum) ) ); sprintf( sendmail, "%s -f%s -F \"%s\" -odb %s", SENDMAIL, pname(mynum), title, cur_player->work_msg->mailto); fptr = popen( sendmail, &type ); if( !fptr ) { bprintf( "Odd, couldn't send the mail. Sorry.\n" ); return; } fprintf( fptr, "Organization: &$ (&H: &P)\n" "X-Mailer: CDirt Mud Mailer (C) Weinerdog and Mancini.\n"); strcpy(tmp_path, cur_player->edit_outfile); if((fd1 = OPEN(tmp_path, O_RDONLY, 0644)) != -1) { while ((numread = read(fd1, buff, MAX_COM_LEN)) > 0) fwrite( buff, numread, 1, fptr ); CLOSE(fd1); } else { bprintf( "Couldn't open temp file\n" ); return; } fputs( ".", fptr ); pclose( fptr ); bprintf( "Internet e-mail sent!\n" ); return; } #endif /* INTERNET_EMAIL */ strcpy(tmp_path, cur_player->edit_outfile); sprintf(mail_path, "%s/%s", MAILDIR, cur_player->work_msg->mailto); if (((fd1 = OPEN(tmp_path, O_RDONLY, 0644)) != -1) && ((fd2 = OPEN(mail_path, O_WRONLY | O_APPEND | O_CREAT, 0664)) != -1)) { while ((numread = read(fd1, buff, MAX_COM_LEN)) > 0) write (fd2, buff, numread); CLOSE(fd1); CLOSE(fd2); /* send received-mail message & update list */ sendto = fpbn(cur_player->work_msg->mailto); if (sendto != -1) { if(players[sendto].inmailer) { tmp_mynum = real_mynum; setup_globals(sendto); loadmail(); listmail(); setup_globals(tmp_mynum); } ssetflg(sendto, SFL_MAIL); sendf(sendto,"&+Y***&+W\a You have received new mail from %s &+Y***\n", pname(mynum)); } else { if( getuaf( cur_player->work_msg->mailto, &p ) ) set_bit( &p.ublock.psflags, SFL_MAIL ); putuaf(&p); } } else { bprintf("Error saving file.\n"); mudlog("ERROR: send_mail\n"); } } void edit1(char *input) { int num, count; if (input == NULL) show_prompt(); else if (edit_status != MENU_MODE && input[0] != '=') { if (input[0] == '*') { if (input[1] == '*') { /* "**" == exit */ if (edit_status == ADD_MODE) { /* adding something in? ifso, link */ if (cur_player->tmp_ptr != NULL) /* have something typed in */ txt_curr->next = cur_player->tmp_ptr; else txt_curr = NULL; } if (cur_player->edit_mode == TYPE_MAIL) strcpy(cur_player->cprompt, MAIL_PROMPT); else if (cur_player->edit_mode == TYPE_DESC) strcpy(cur_player->cprompt, DESC_PROMPT); else strcpy(cur_player->cprompt, EDIT_PROMPT); edit_status = MENU_MODE; } else { /* game command */ replace_input_handler(cur_player->edit_inp_handler); gamecom(input+1, True); edit1(NULL); } } else { /* normal case: add this line of text */ new_line(input); show_prompt(); } } else if (edit_status == MENU_MODE || input[0] == '=') { /* MENU MODE or =command */ switch ((input[0] == '=') ? tolower(input[1]) : tolower(input[0])) { case 'c': /* cancel */ if (cur_player->edit_mode == TYPE_MAIL) bprintf("Message cancelled.\n"); else bprintf("Buffer &+Ynot &Nsaved.\n"); free_list(); clean_up(); return; case 'e': case 'x': case 'q': /* save/exit */ save_buff(cur_player->edit_outfile, cur_player->edit_mode); if (cur_player->edit_mode == TYPE_MAIL) send_mail(); free_list(); clean_up(); return; case 'd': /* delete a line */ if ((count = getnum(input, &num)) != -1) { if (count == 1) bprintf("[Line %d deleted]\n", num); else bprintf("[Lines %d through %d deleted]\n", num, num + count - 1); while (count-- > 0) delete_line(num); } break; case 'i': /* add a line */ if ((getnum(input, &num)) != -1) { curr_line = num + 1; add_lines(num); } break; case '?': case 'h': /* help */ editor_help(); break; case 'n': /* new buffer */ free_list(); add_lines(0); break; case 's': /* save buffer */ save_buff(cur_player->edit_outfile, cur_player->edit_mode); break; case '\0': case 'v': /* view buffer */ view_text(); break; default: bprintf("Command Invalid; Type ? for help.\n"); break; } if (edit_status == MENU_MODE) bprintf(EDIT_PROMPT); else if (input[0] == '=' && input[1] != 'n' && input[1] != 'i') show_prompt(); } replace_input_handler(edit1); }