wmark@wb3ffv.ampr.org (Mark Winsor) (10/13/90)
Here is a binary editor that i've found useful. It has only been tested in SYSV & SCO XENIX environments, but should be relatively easy to port. Do to the non-standard alternate character set mapping prior to SYSV3, the line drawing characters are replaced with, |, -, and + for those environments (or if your terminal doesn't support line drawing charaters). Mark S. Winsor Systems Analyst ProVAR, Inc. -------------------------------CUT HERE--------------------------------- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./Makefile` then echo "writing ./Makefile" cat > ./Makefile << '\Rogue\Monster\' # The XENIX define is used for any system that uses xenix style echoing OBJS = filepatch.o bxline.o getword.o getattrs.o SOURCE = filepatch.c bxline.c getword.c getattrs.c make: @echo "You must specify system type (i.e. sys5.3 or sco, etc)" sys5.3: make filepatch "FLAGS = -O -g -c -D SYSV3"\ "LDFLAGS = -g -lcurses" ncr: make filepatch "FLAGS = -O -c -D XENIX"\ "LDFLAGS = -s -lcurses" sco: make filepatch "FLAGS = -O -c -D SCO286"\ "LDFLAGS = -s -Ml -F 4000 -lx -lcurses" clean: rm -f *\.o filepatch core filepatch: $(OBJS) cc $(OBJS) -o filepatch $(LDFLAGS) .c.o: cc $(FLAGS) $*.c \Rogue\Monster\ else echo "will not over write ./Makefile" fi if `test ! -s ./bxline.c` then echo "writing ./bxline.c" cat > ./bxline.c << '\Rogue\Monster\' /* * This is a routine to place a solid line border * around a window. Mark S. Winsor * ProVAR */ static char rcsid[] = "$Id: bxline.c,v 1.2 90/10/10 21:03:48 wmark Exp $"; static char rcsrev[] = "$Revision: 1.2 $"; /* $Author: wmark $ $Date: 90/10/10 21:03:48 $ $Locker: $ $RCSfile: bxline.c,v $ $Source: /usr9/people/mark/C/filepatch/bxline.c,v $ $State: Exp $ $Log: bxline.c,v $ * Revision 1.2 90/10/10 21:03:48 wmark * Took out color * * Revision 1.1 90/07/29 18:00:24 wmark * Initial revision * */ #include <curses.h> #ifdef SCO286 #define XENIX #endif bxline(towindow, vert_len, horz_len ) char *towindow; int vert_len; int horz_len; { int a; int b; int line; extern int altchar; char *acsc_ptr; char acsc_arr[80]; char upperright; char upperleft; char lowerright; char lowerleft; char horizontal; char vertical; #ifdef SYSV3 upperright = ACS_URCORNER; upperleft = ACS_ULCORNER; lowerright = ACS_LRCORNER; lowerleft = ACS_LLCORNER; horizontal = ACS_HLINE; vertical = ACS_VLINE; #else upperright = '+'; upperleft = '+'; lowerright = '+'; lowerleft = '+'; horizontal = '-'; vertical = '|'; #endif #ifdef SYSV3 (void) wattrset(towindow,A_ALTCHARSET); #endif (void) mvwprintw(towindow,0,0,"%c",upperleft); (void) mvwprintw(towindow,0,(horz_len - 1),"%c",upperright); (void) mvwprintw(towindow,(vert_len - 1),0,"%c",lowerleft); (void) mvwprintw(towindow,(vert_len - 1),(horz_len - 1),"%c", lowerright); a = 0; b = horz_len - 1; line = 1; while ( line < (vert_len - 1)) { (void) mvwprintw (towindow,line,a,"%c",vertical); (void) mvwprintw (towindow,line,b,"%c",vertical); ++line; } a = 0; for ( b = 1; b < (horz_len - 1); ++b) { (void) mvwprintw (towindow,a,b,"%c",horizontal); } a = vert_len - 1; for ( b = 1; b < (horz_len - 1); ++b) { (void) mvwprintw (towindow,a,b,"%c",horizontal); } (void) wrefresh(towindow); (void) wattrset(towindow,0); } \Rogue\Monster\ else echo "will not over write ./bxline.c" fi if `test ! -s ./filepatch.c` then echo "writing ./filepatch.c" cat > ./filepatch.c << '\Rogue\Monster\' /* * Norton-esque file patch utility program * * Copyright ProVAR, Inc. & * Emtronix Data Services * * Mark S. Winsor * Marc A. Siegel * * This program may be freely distributed provided this notice remains * * Send any bug reports, questions, or suggestions to * {uunet}!cp1!briar!mas!bohica!wmark */ static char rcsid[] = "$Id: filepatch.c,v 1.12 90/10/10 21:03:24 wmark Exp $"; static char rcsrev[] = "$Revision: 1.12 $"; /* $Author: wmark $ $Date: 90/10/10 21:03:24 $ $Locker: $ $RCSfile: filepatch.c,v $ $Source: /usr9/people/mark/C/filepatch/filepatch.c,v $ $State: Exp $ $Log: filepatch.c,v $ * Revision 1.12 90/10/10 21:03:24 wmark * fixed display * * Revision 1.11 90/08/13 12:53:42 wmark * Repeat last search if no argument given * * Revision 1.9 90/08/13 10:15:28 wmark * Added relative offsets (using "+" or "-" in first character of offset) * * Revision 1.3 90/07/30 09:26:07 wmark * Centered title line * * Revision 1.2 90/07/29 18:19:44 wmark * Use RCS revision number in title line * * Revision 1.1 90/07/29 18:17:58 wmark * Initial revision * */ #include <curses.h> #include <ctype.h> #include <fcntl.h> #include <signal.h> #include <errno.h> #define ESC '\033' #define TAB '\011' #define NUMBUF 25 #define MAX 256 #define MAXPAT 40 #define MAXHEX 20 #ifdef SCO286 #define XENIX #endif int colors; int blink; int reverse; int altchar; int underline; int edit_type; /* 0 = edit hex, 1 = edit chars */ char lastsearch[MAXPAT]; struct scr_pos { int h_scr_row; int h_scr_col; int c_scr_row; int c_scr_col; }; /* * This table below is used instead of printw("%X") for two reasons. * 1 - speed, and 2 - there appears to be a problem with printf type * commands printing hex FF on Xenix and ncr systems. */ char *hexconv[] = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" }; main(argc,argv) int argc; char *argv[]; { int input; if (argc != 2) { (void) usage(argv[0]); } if ((input = open(argv[1],O_RDWR)) == -1) { (void) fprintf(stderr,"%s: Cannot open %s, error %d\n", argv[0],argv[1],errno); (void) exit(1); } edit_type = 0; lastsearch[0] = '\0'; (void) process_file (input,argv[1]); (void) close(input); (void) exit(0); } process_file(input,filename) int input; char *filename; { static char buffer[MAX]; long seek_no; int max; int proc_ret; int byebye(); long end_of_file; long lseek(); (void) initscr(); (void) raw(); #ifndef XENIX (void) noecho(); #endif (void) keypad(stdscr,TRUE); (void) signal(SIGINT,byebye); (void) signal(SIGQUIT,byebye); (void) get_attrs(); (void) bxline(stdscr,23,80); if (reverse == TRUE) { (void) attrset(A_REVERSE); } (void) mvprintw(0,20," ProVAR File Patch Utility "); (void) printw("Rev: %c%c%c%c ",rcsrev[11],rcsrev[12],rcsrev[13],rcsrev[14]); (void) attrset(0); (void) mvprintw(2,3,"File Name: %-40.40s",filename); (void) mvprintw(21,28,"Enter '?' for help"); seek_no = 0; end_of_file = lseek(input,0L,2); for (;;) { (void) mvprintw(2,55,"Offset: %7ld bytes",seek_no); (void) move(23,0); (void) clrtoeol(); if (lseek(input,seek_no,0) == -1) break; max = read(input,buffer,MAX); if (max < 1) break; proc_ret = process_buf(buffer,max,&seek_no,end_of_file,input); if (proc_ret == -1) break; if (proc_ret == 1) { if (lseek(input,seek_no,0) == -1) break; (void) write(input,buffer,max); } } (void) erase(); (void) mvprintw(12,25,"-- Finished Processing --"); (void) refresh(); (void) endwin(); } process_buf(buffer,max,seek_ptr,end_of_file,input) char *buffer; int max; long *seek_ptr; long end_of_file; int input; { int index; for (index = 0; index < max; index++) { (void) disp_char(*(buffer + index),index); } for ( ; index < MAX; index++) { (void) erase_char(index); } return(update_buf(buffer,max,seek_ptr,end_of_file,input)); } update_buf(buffer,max,seek_ptr,end_of_file,input) char *buffer; int max; long *seek_ptr; long end_of_file; int input; { struct scr_pos pos; unsigned int i; int index; int oldindex; long new_offset; long get_new_offset(); long get_pattern(); long lseek(); int c; char chgs_made; char answer; char mode; char hex_string[3]; mode = 'C'; /* C = Command, E = Edit */ index = 0; chgs_made = 'N'; for (;;) { if (mode == 'C') { (void) mvprintw(23,0,"Command Mode"); (void) refresh(); } else { (void) mvprintw(23,0,"Edit mode "); (void) refresh(); } (void) pos_char(index,&pos); if (edit_type == 0) { (void) move (pos.h_scr_row,pos.h_scr_col); } else { (void) move (pos.c_scr_row,pos.c_scr_col); } (void) refresh(); c = getch(); if (mode == 'E') { switch(c) { case ESC: case TAB: mode = 'C'; break; default: if (edit_type == 0) { c = toupper(c); hex_string[0] = c; (void) move (pos.h_scr_row,(pos.h_scr_col + 1)); (void) refresh(); c = getch(); c = toupper(c); hex_string[1] = c; hex_string[2] = '\0'; if (hex_string[0] < '0' || hex_string[0] > '9') { if (hex_string[0] < 'A' || hex_string[0] > 'F') { (void) beep(); break; } } if (hex_string[1] < '0' || hex_string[1] > '9') { if (hex_string[1] < 'A' || hex_string[1] > 'F') { (void) beep(); break; } } (void) sscanf(hex_string,"%x",&i); } else { i = c; } *(buffer + index) = i; (void) disp_char(*(buffer + index),index); chgs_made = 'Y'; ++index; if (index >= max) index = 0; break; } } else { switch(c) { case ESC: case TAB: mode = 'E'; break; case 'W': case 'w': (void) mvprintw(23,0,"... Writing "); (void) refresh(); return(1); case 'E': case 'e': *seek_ptr = end_of_file - 256; if (*seek_ptr < 0) { *seek_ptr = 0; } return(0); case 'Q': case 'q': if (chgs_made == 'Y') { answer = ask_ignore(); } if (chgs_made == 'Y' && answer == 'N') { break; } else { return(-1); } case '?': (void) help(); break; case 'T': case 't': edit_type ^= 1; break; case 'O': case 'o': new_offset = get_new_offset(*seek_ptr); if (new_offset < 0 || new_offset > end_of_file) { (void) error("Offset out of range"); break; } else { *seek_ptr = new_offset; return(0); } case '/': if (chgs_made == 'Y') { answer = ask_ignore(); } if (chgs_made == 'Y' && answer == 'N') { break; } else { new_offset = get_pattern((*seek_ptr + index), buffer,max,input); (void) move(23,0); (void) clrtoeol(); (void) refresh(); if (new_offset == -1) { /* Not found */ (void) error("Pattern not found"); break; } if (new_offset == -2) { /*Not fnd */ (void) error("Pattern not found"); /*re-read */ lseek(input,*seek_ptr,0); /*required*/ max = read(input,buffer,MAX); break; } if (new_offset == -3) { break; } else { *seek_ptr = new_offset; return(0); } } case KEY_RIGHT: case 'R': case 'r': ++index; if (index > max) { --index; (void) beep(); } break; case KEY_LEFT: case 'L': case 'l': --index; if (index < 0) { index = 0; (void) beep(); } break; case KEY_DOWN: case 'D': case 'd': index += 16; if (index >= max) { index -= 16; (void) beep(); } break; case KEY_UP: case 'U': case 'u': index -= 16; if (index < 0) { index += 16; (void) beep(); } break; case '\n': oldindex = index; index += 16; index = index - (index % 16); if (index >= max) { index = oldindex; (void) beep(); } break; case 'F': case 'f': if (chgs_made == 'Y') { answer = ask_ignore(); } if (chgs_made == 'Y' && answer == 'N') { break; } else { *seek_ptr += MAX; if (*seek_ptr >= end_of_file) { (void) error("No pages after this one"); *seek_ptr -= MAX; break; } else { return(0); } } case 'B': case 'b': if (chgs_made == 'Y') { answer = ask_ignore(); } if (chgs_made == 'Y' && answer == 'N') { break; } else { if (*seek_ptr == 0) { (void) error("No pages before this one"); break; } else { *seek_ptr -= MAX; if (*seek_ptr < 0) *seek_ptr = 0; return(0); } } default: (void) beep(); break; } } } } ask_ignore() { int answer; (void) mvprintw(23,0, "This will ignore changes in this block, "); (void) printw("Is this ok ? "); do { (void) move(23,53); (void) refresh(); answer = getch(); answer = toupper(answer); (void) move(23,53); (void) addch(answer); (void) refresh(); } while(answer != 'N' && answer != 'Y'); (void) move(23,0); (void) clrtoeol(); return(answer); } long get_new_offset(oldoffset) long oldoffset; { long offset; char offsetbuf[15]; #ifndef XENIX (void) echo(); #endif (void) mvprintw(23,0,"Enter Offset: "); offsetbuf[0] = '\0'; (void) get_word(14,offsetbuf,stdscr,23,14); if (offsetbuf[0] == '\0') { offset = -1; } else if (offsetbuf[0] == '+' || offsetbuf[0] == '-') { if ((sscanf(offsetbuf,"%ld",&offset)) != 1) { offset = -1; } else { offset += oldoffset; } } else { if ((sscanf(offsetbuf,"%ld",&offset)) != 1) { offset = -1; } } (void) move(23,0); (void) clrtoeol(); #ifndef XENIX (void) noecho(); #endif return(offset); } long get_pattern(offset,buffer,max,input) long offset; char *buffer; int max; int input; { static char pat[MAXPAT]; int wordresult; long search(); #ifndef XENIX (void) echo(); #endif (void) mvprintw(23,0,"Enter pattern (ESC to enter in hex): "); pat[0] = '\0'; wordresult = get_word(MAXPAT,pat,stdscr,23,37); if (wordresult == 6) { /* The get_word() func is overkill */ (void) hex_pattern(pat); /* but I use it often in other */ } /* things, so why re-invent the wheel! */ if (pat[0] == '\0') { #ifndef XENIX (void) noecho(); #endif if (lastsearch[0] == '\0') { return(-3); } else { (void) strcpy(pat,lastsearch); } } (void) move(23,0); (void) clrtoeol(); (void) mvprintw(23,0,"... Searching"); (void) refresh(); #ifndef XENIX (void) noecho(); #endif (void) strcpy(lastsearch,pat); return(search(pat,buffer,offset,max,input)); } hex_pattern(pat) char *pat; { int i; int j; int c; char hex_string[3]; #ifndef XENIX (void) noecho(); #endif (void) move(23,0); (void) clrtoeol(); (void) mvprintw(23,0,"Enter hex characters:"); (void) refresh(); i = 0; do { (void) move(23,(22 + (i * 3))); (void) refresh(); c = getch(); if (c != '\n') { hex_string[0] = c; hex_string[1] = getch(); hex_string[2] = '\0'; if (sscanf(hex_string,"%x",&c) != 1) { (void) beep(); } else { *(pat + i) = c; (void) mvaddstr(23,(22 + (i * 3)), hexconv[(unsigned int)*(pat + i)]); (void) refresh(); c = '\0'; ++i; } } } while (c != '\n' && i < MAXHEX); ++i; *(pat + i) = '\0'; #ifndef XENIX (void) echo(); #endif } long search(pat,buffer,offset,max,input) char *pat; char *buffer; long offset; int max; int input; { register int index; int pat_length; char re_read; static char srch_buf[MAX * NUMBUF]; char *search_buf; long lseek(); re_read = 'N'; pat_length = strlen(pat); (void) memcpy(srch_buf,buffer,max); search_buf = srch_buf; for (;;) { for (index = 1; index < (max - pat_length + 1); index++) { if (*(search_buf + index) == *pat) { if (!memcmp((search_buf + index),pat,pat_length)) { return(index + offset); } } } if (max < MAX) { if (re_read == 'N') { return(-1); } else { return(-2); } } offset += max; if (lseek(input,offset,0) == -1) { if (re_read == 'N') { return(-1); } else { return(-2); } } max = read(input,srch_buf,(MAX * NUMBUF)); re_read = 'Y'; } } disp_char(c,index) unsigned char c; int index; { struct scr_pos pos; (void) pos_char(index,&pos); (void) mvaddstr(pos.h_scr_row,pos.h_scr_col,hexconv[(unsigned int)c]); if (c < ' ' || c > '~') { c = '.'; } (void) mvaddch(pos.c_scr_row,pos.c_scr_col,c); } erase_char(index) int index; { struct scr_pos pos; (void) pos_char(index,&pos); (void) mvprintw(pos.h_scr_row,pos.h_scr_col," "); (void) mvprintw(pos.c_scr_row,pos.c_scr_col," "); } pos_char(index,posptr) int index; struct scr_pos *posptr; { int st_row; int st_col; int calc_row; int calc_rem; int even_odd; st_row = 4; st_col = 2; calc_row = index / 16; calc_rem = index % 16; even_odd = calc_rem % 2; even_odd ^= 1; /* If 0 make it one, and vice versa */ posptr->h_scr_row = posptr->c_scr_row = st_row + calc_row; posptr->h_scr_col = (st_col + (calc_rem * 3) + (even_odd * 1)); posptr->c_scr_col = st_col + 52 + calc_rem; return(0); } help() { WINDOW *helpwin; helpwin = newwin(20,48,1,15); bxline(helpwin,20,48); (void) mvwprintw(helpwin,1,15,"Action Key List"); (void) mvwprintw(helpwin,3,3,"ESC or TAB toggles edit/command mode"); (void) mvwprintw(helpwin,4,3,"R or Right arrow = Move to right"); (void) mvwprintw(helpwin,5,3,"L or Left arrow = Move to left"); (void) mvwprintw(helpwin,6,3,"D or Down arrow = Down one line"); (void) mvwprintw(helpwin,7,3,"U or Up arrow = Up one line"); (void) mvwprintw(helpwin,8,3,"<RETURN> = Beginning of next line"); (void) mvwprintw(helpwin,9,3,"W = Write current buffer"); (void) mvwprintw(helpwin,10,3,"Q = Quit processing"); (void) mvwprintw(helpwin,11,3,"F = Forward page"); (void) mvwprintw(helpwin,12,3,"B = Backward page"); (void) mvwprintw(helpwin,13,3,"O = Change offset"); (void) mvwprintw(helpwin,14,3,"E = Go to last page"); (void) mvwprintw(helpwin,15,3,"T = Toggle hex/char edit"); (void) mvwprintw(helpwin,16,3,"/ = Pattern match"); (void) mvwprintw(helpwin,18,3,"Press Any key to continue "); (void) wrefresh(helpwin); (void) wgetch(helpwin); (void) delwin(helpwin); (void) touchwin(stdscr); } error(str) char *str; { (void) mvprintw(23,0,"%s ",str); (void) refresh(); (void) beep(); (void) getch(); (void) move(23,0); (void) clrtoeol(); } usage(progname) char *progname; { (void) fprintf(stderr,"Usage: %s filename\n",progname); (void) exit(1); } byebye() { (void) endwin(); (void) exit(2); } \Rogue\Monster\ else echo "will not over write ./filepatch.c" fi if `test ! -s ./getattrs.c` then echo "writing ./getattrs.c" cat > ./getattrs.c << '\Rogue\Monster\' static char rcsid[] = "$Id: getattrs.c,v 1.1 90/07/29 18:00:32 wmark Exp $"; static char rcsrev[] = "$Revision: 1.1 $"; /* $Author: wmark $ $Date: 90/07/29 18:00:32 $ $Locker: $ $RCSfile: getattrs.c,v $ $Source: /usr9/people/mark/C/filepatch/getattrs.c,v $ $State: Exp $ $Log: getattrs.c,v $ * Revision 1.1 90/07/29 18:00:32 wmark * Initial revision * */ #include <curses.h> #ifdef SCO286 #define XENIX #endif get_attrs() { extern int blink; extern int colors; extern int reverse; extern int altchar; extern int underline; char sm[30]; blink = FALSE; colors = FALSE; reverse = FALSE; altchar = FALSE; underline = FALSE; #ifdef XENIX if (((char *) tgetstr("bm",sm)) != NULL) { blink = TRUE; } if (((char *) tgetstr("so",sm)) != NULL) { reverse = TRUE; } if (((char *) tgetstr("as",sm)) != NULL) { altchar = TRUE; } if (((char *) tgetstr("us",sm)) != NULL) { underline = TRUE; } #else if (((char *) tigetstr("blink")) != NULL) { blink = TRUE; } if (((char *) tigetstr("smso")) != NULL) { reverse = TRUE; } altchar = TRUE; if (((char *) tigetstr("smul")) != NULL) { underline = TRUE; } #endif #ifdef USECOLORS colors = start_color(); if (colors != ERR) { colors = TRUE; } #endif } \Rogue\Monster\ else echo "will not over write ./getattrs.c" fi if `test ! -s ./getword.c` then echo "writing ./getword.c" cat > ./getword.c << '\Rogue\Monster\' /* This is a common accept routine for all character and character string input. Mark S. Winsor ProVAR */ static char rcsid[] = "$Id: getword.c,v 1.1 90/07/29 18:00:37 wmark Exp $"; static char rcsrev[] = "$Revision: 1.1 $"; /* $Author: wmark $ $Date: 90/07/29 18:00:37 $ $Locker: $ $RCSfile: getword.c,v $ $Source: /usr9/people/mark/C/filepatch/getword.c,v $ $State: Exp $ $Log: getword.c,v $ * Revision 1.1 90/07/29 18:00:37 wmark * Initial revision * */ #include <curses.h> #define CTRLA '\001' #define CTRLB '\002' #define CTRLC '\003' #define CTRLD '\004' #define CTRLT '\024' #define BELL '\007' #define REPAINT '\014' #ifndef ESC #define ESC '\033' #endif #ifdef SCO286 #define XENIX #endif get_word(size,fld_ptr,fromwindow,beg_row,beg_col) int size; char *fld_ptr; char *fromwindow; int beg_row; int beg_col; { int offset; int ch; char fill_flag = 'y'; /* * Keypad must be enabled to use this function, * the arrow keys will return : * 1 for KEY_UP, KEY_F2, * 2 for KEY_LEFT, KEY_F3, * 3 for KEY_DOWN, KEY_F1, * 4 for KEY_RIGHT, KEY_F4, * and 0 for no arrow */ #ifndef XENIX (void) noecho(); #endif (void) wmove(fromwindow,beg_row,beg_col); (void) wrefresh(fromwindow); for (;;) { for (offset = 0; offset < size; offset++) { ch = wgetch(fromwindow); if (ch == REPAINT && offset == 0) { /* If CTRL-L is */ (void) wmove (fromwindow,beg_row,beg_col); /* is pressed */ (void) wprintw(fromwindow," "); /* in the 1'st */ (void) wmove (fromwindow,beg_row,beg_col); /* postition, */ (void) clearok(fromwindow); /* then repaint */ (void) wrefresh(fromwindow); /* screen and */ --offset; /* continue */ continue; } if (offset == 0) { if (ch == ESC) { return(6); } if (ch == KEY_UP || ch == CTRLB) { return(1); } if (ch == KEY_RIGHT || ch == CTRLD) { return(4); } if (ch == KEY_DOWN || ch == CTRLA) { return(3); } if (ch == KEY_LEFT || ch == CTRLC) { return(2); } if (ch == CTRLT) { return(6); } } if (ch == '\n' && offset == 0) { return(0); } if (ch == '\n') { *(fld_ptr + offset) = '\0'; fill_flag = 'n'; return(0); } if (ch == '\b') { offset = offset - 2; if (offset < -1) { (void) putchar(BELL); (void) mvwprintw(fromwindow,beg_row,beg_col," "); (void) wrefresh(fromwindow); (void) wmove(fromwindow,beg_row,beg_col); (void) wrefresh(fromwindow); *fld_ptr = '\0'; offset = -1; } else { /* Mimic a Unix */ (void) wmove (fromwindow,beg_row,(beg_col + offset + 1)); /* stty echoe */ (void) wprintw(fromwindow, " "); (void) wprintw(fromwindow, " "); (void) wrefresh(fromwindow); (void) wmove (fromwindow,beg_row,(beg_col + offset + 1)); (void) wrefresh(fromwindow); *(fld_ptr + (offset + 1)) = '\0'; } } if (offset == 0) { (void) clr_fld(size,fromwindow,beg_row,beg_col); (void) wmove (fromwindow, beg_row, (beg_col + 1)); (void) wrefresh (fromwindow); } if (ch != '\b') { *(fld_ptr + offset) = ch; (void) wmove (fromwindow,beg_row,(beg_col + offset)); (void) waddch(fromwindow,ch); (void) wrefresh (fromwindow); } } if (fill_flag == 'y') { if (size > 1) { *(fld_ptr + offset) = '\0'; } } #ifndef XENIX (void) echo(); #endif break; } } clr_fld (size, fromwindow, beg_row, beg_col) int size; int beg_row; int beg_col; char *fromwindow; { int i; for (i = (beg_col+1); i < (beg_col+size); ++i) { (void) mvwprintw(fromwindow,beg_row,i," "); } (void) wrefresh(fromwindow); } \Rogue\Monster\ else echo "will not over write ./getword.c" fi echo "Finished archive 1 of 1" exit