/* * note.c */ #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <sys/stat.h> #include <string.h> #include <stdarg.h> #include <ctype.h> #include <stdlib.h> #include <math.h> #include "mud.h" NOTE_DATA *note_free; NOTE_DATA *note_list; /* Date stamp idea comes from Alander of ROM */ void cmd_note( D_MOBILE * ch, char *argument ) { char buf[MAX_BUFFER]; char buf1[MAX_BUFFER]; char arg[MAX_BUFFER]; NOTE_DATA *pnote; int vnum; int anum; buf1[0] = '\0'; argument = one_arg( argument, arg ); smash_tilde( argument ); if( arg[0] == '\0' ) { cmd_note( ch, "read" ); return; } if( compares( arg, "list" ) ) { vnum = 0; for( pnote = note_list; pnote != NULL; pnote = pnote->next ) { if( is_note_to( ch, pnote ) ) { sprintf( buf, "[%3d%s] %s: %s\r\n", vnum, ( pnote->date_stamp > ch->last_note && compares( pnote->sender, ch->name ) ) ? "N" : " ", pnote->sender, pnote->subject ); strcat( buf1, buf ); vnum++; } } send_to_char( buf1, ch ); return; } if( compares( arg, "read" ) ) { bool fAll; if( compares( argument, "all" ) ) { fAll = TRUE; anum = 0; } else if( argument[0] == '\0' || !is_prefix( argument, "next" ) ) /* * read next unread note */ { vnum = 0; for( pnote = note_list; pnote != NULL; pnote = pnote->next ) { if( is_note_to( ch, pnote ) && compares( ch->name, pnote->sender ) && ch->last_note < pnote->date_stamp ) { sprintf( buf, "[%3d] %s: %s\r\n%s\r\nTo: %s\r\n", vnum, pnote->sender, pnote->subject, pnote->date, pnote->to_list ); strcat( buf1, buf ); strcat( buf1, pnote->text ); ch->last_note = UMAX( ch->last_note, pnote->date_stamp ); send_to_char( buf1, ch ); return; } else vnum++; } send_to_char( "You have no unread notes.\r\n", ch ); return; } else if( is_number( argument ) ) { fAll = FALSE; anum = atoi( argument ); } else { send_to_char( "Note read which number?\r\n", ch ); return; } vnum = 0; for( pnote = note_list; pnote != NULL; pnote = pnote->next ) { if( is_note_to( ch, pnote ) && ( vnum++ == anum || fAll ) ) { sprintf( buf, "[%3d] %s: %s\r\n%s\r\nTo: %s\r\n", vnum - 1, pnote->sender, pnote->subject, pnote->date, pnote->to_list ); strcat( buf1, buf ); strcat( buf1, pnote->text ); send_to_char( buf1, ch ); ch->last_note = UMAX( ch->last_note, pnote->date_stamp ); return; } } send_to_char( "No such note.\r\n", ch ); return; } if( compares( arg, "+" ) ) { note_attach( ch ); strcpy( buf, ch->pnote->text ); if( strlen( buf ) + strlen( argument ) >= MAX_BUFFER - 200 ) { send_to_char( "Note too long.\r\n", ch ); return; } strcat( buf, argument ); strcat( buf, "\r\n" ); free( ch->pnote->text ); ch->pnote->text = strdup( buf ); send_to_char( "Ok.\r\n", ch ); return; } if( compares( arg, "subject" ) ) { note_attach( ch ); free( ch->pnote->subject ); ch->pnote->subject = strdup( argument ); send_to_char( "Ok.\r\n", ch ); return; } if( compares( arg, "to" ) ) { note_attach( ch ); free( ch->pnote->to_list ); ch->pnote->to_list = strdup( argument ); send_to_char( "Ok.\r\n", ch ); return; } if( compares( arg, "clear" ) ) { if( ch->pnote != NULL ) { free( ch->pnote->text ); free( ch->pnote->subject ); free( ch->pnote->to_list ); free( ch->pnote->date ); free( ch->pnote->sender ); ch->pnote->next = note_free; note_free = ch->pnote; ch->pnote = NULL; } send_to_char( "Ok.\r\n", ch ); return; } if( compares( arg, "show" ) ) { if( ch->pnote == NULL ) { send_to_char( "You have no note in progress.\r\n", ch ); return; } sprintf( buf, "%s: %s\r\nTo: %s\r\n", ch->pnote->sender, ch->pnote->subject, ch->pnote->to_list ); send_to_char( buf, ch ); send_to_char( ch->pnote->text, ch ); return; } if( compares( arg, "post" ) || !is_prefix( arg, "send" ) ) { FILE *fp; char *strtime; if( ch->pnote == NULL ) { send_to_char( "You have no note in progress.\r\n", ch ); return; } if( compares( ch->pnote->to_list, "" ) ) { send_to_char( "You need to provide a recipient (name, all, or immortal).\r\n", ch ); return; } if( compares( ch->pnote->subject, "" ) ) { send_to_char( "You need to provide a subject.\r\n", ch ); return; } ch->pnote->next = NULL; strtime = ctime( ¤t_time ); strtime[strlen( strtime ) - 1] = '\0'; ch->pnote->date = strdup( strtime ); ch->pnote->date_stamp = current_time; if( note_list == NULL ) { note_list = ch->pnote; } else { for( pnote = note_list; pnote->next != NULL; pnote = pnote->next ) ; pnote->next = ch->pnote; } pnote = ch->pnote; ch->pnote = NULL; if( ( fp = fopen( NOTE_FILE, "a" ) ) == NULL ) { perror( NOTE_FILE ); } else { fprintf( fp, "Sender %s~\n", pnote->sender ); fprintf( fp, "Date %s~\n", pnote->date ); fprintf( fp, "Stamp %ld\n", pnote->date_stamp ); fprintf( fp, "To %s~\n", pnote->to_list ); fprintf( fp, "Subject %s~\n", pnote->subject ); fprintf( fp, "Text\n%s~\n\n", pnote->text ); fclose( fp ); } send_to_char( "Ok.\r\n", ch ); return; } if( compares( arg, "remove" ) ) { if( !is_number( argument ) ) { send_to_char( "Note remove which number?\r\n", ch ); return; } anum = atoi( argument ); vnum = 0; for( pnote = note_list; pnote != NULL; pnote = pnote->next ) { if( is_note_to( ch, pnote ) && vnum++ == anum ) { note_remove( ch, pnote ); send_to_char( "Ok.\r\n", ch ); return; } } send_to_char( "No such note.\r\n", ch ); return; } send_to_char( "Huh? Type 'help note' for usage.\r\n", ch ); return; } bool is_note_to( D_MOBILE * ch, NOTE_DATA * pnote ) { if( compares( ch->name, pnote->sender ) ) return TRUE; if( is_name( "all", pnote->to_list ) ) return TRUE; if( is_name( ch->name, pnote->to_list ) ) return TRUE; return FALSE; } void note_attach( D_MOBILE * ch ) { NOTE_DATA *pnote; if( ch->pnote != NULL ) return; if( note_free == NULL ) { pnote = malloc( sizeof( *ch->pnote ) ); } else { pnote = note_free; note_free = note_free->next; } pnote->next = NULL; pnote->sender = strdup( ch->name ); pnote->date = strdup( "" ); pnote->to_list = strdup( "" ); pnote->subject = strdup( "" ); pnote->text = strdup( "" ); ch->pnote = pnote; return; } void note_remove( D_MOBILE * ch, NOTE_DATA * pnote ) { char to_new[MAX_BUFFER]; char to_one[MAX_BUFFER]; FILE *fp; NOTE_DATA *prev; char *to_list; /* * Build a new to_list. * Strip out this recipient. */ to_new[0] = '\0'; to_list = pnote->to_list; while( *to_list != '\0' ) { to_list = one_arg( to_list, to_one ); if( to_one[0] != '\0' && !compares( ch->name, to_one ) ) { strcat( to_new, " " ); strcat( to_new, to_one ); } } /* * Just a simple recipient removal? */ if( compares( ch->name, pnote->sender ) && to_new[0] != '\0' ) { free( pnote->to_list ); pnote->to_list = strdup( to_new + 1 ); return; } /* * Remove note from linked list. */ if( pnote == note_list ) { note_list = pnote->next; } else { for( prev = note_list; prev != NULL; prev = prev->next ) { if( prev->next == pnote ) break; } if( prev == NULL ) { bug( "Note_remove: pnote not found.", 0 ); return; } prev->next = pnote->next; } free( pnote->text ); free( pnote->subject ); free( pnote->to_list ); free( pnote->date ); free( pnote->sender ); pnote->next = note_free; note_free = pnote; /* * Rewrite entire list. */ if( ( fp = fopen( NOTE_FILE, "w" ) ) == NULL ) { perror( NOTE_FILE ); } else { for( pnote = note_list; pnote != NULL; pnote = pnote->next ) { fprintf( fp, "Sender %s~\n", pnote->sender ); fprintf( fp, "Date %s~\n", pnote->date ); fprintf( fp, "Stamp %ld\n", pnote->date_stamp ); fprintf( fp, "To %s~\n", pnote->to_list ); fprintf( fp, "Subject %s~\n", pnote->subject ); fprintf( fp, "Text\n%s~\n\n", pnote->text ); } fclose( fp ); } return; } /* * Snarf notes file. */ void load_notes( void ) { FILE *fp; NOTE_DATA *pnotelast; if( ( fp = fopen( NOTE_FILE, "r" ) ) == NULL ) return; pnotelast = NULL; for( ;; ) { NOTE_DATA *pnote; char letter; do { letter = getc( fp ); if( feof( fp ) ) { fclose( fp ); return; } } while( isspace( letter ) ); ungetc( letter, fp ); pnote = malloc( sizeof( *pnote ) ); if( !compares( fread_word( fp ), "sender" ) ) break; pnote->sender = fread_string( fp ); if( !compares( fread_word( fp ), "date" ) ) break; pnote->date = fread_string( fp ); if( !compares( fread_word( fp ), "stamp" ) ) break; pnote->date_stamp = fread_number( fp ); if( !compares( fread_word( fp ), "to" ) ) break; pnote->to_list = fread_string( fp ); if( !compares( fread_word( fp ), "subject" ) ) break; pnote->subject = fread_string( fp ); if( !compares( fread_word( fp ), "text" ) ) break; pnote->text = fread_string( fp ); if( note_list == NULL ) note_list = pnote; else pnotelast->next = pnote; pnotelast = pnote; } bug( "Load_notes: bad key word."); exit( 1 ); return; } bool is_number( char *arg ) { if( *arg == '\0' ) return FALSE; if( *arg == '+' || *arg == '-' ) arg++; for( ; *arg != '\0'; arg++ ) { if( !isdigit( *arg ) ) return FALSE; } return TRUE; } bool is_name( const char *str, char *namelist ) { char name[MAX_BUFFER]; for( ;; ) { namelist = one_arg( namelist, name ); if( name[0] == '\0' ) return FALSE; if( compares( str, name ) ) return TRUE; } }