1 /***************************************************************************
2  *
3  * $Header: /usr/local/cvsroot/utils/ytree/view.c,v 1.26 2014/12/26 09:53:11 werner Exp $
4  *
5  * View-Kommando-Bearbeitung
6  *
7  ***************************************************************************/
8 
9 
10 #include "ytree.h"
11 #include <errno.h>
12 #include "xmalloc.h"
13 
14 typedef struct MODIF {
15     long pos;
16     unsigned char old_char;
17     unsigned char new_char;
18     struct MODIF *next;
19 } CHANGES;
20 
21 static CHANGES *changes;
22 static int cursor_pos_x;
23 static int cursor_pos_y;
24 
25 static long current_line;
26 static int fd, fd2;
27 static struct stat fdstat;
28 static int WLINES, WCOLS, BYTES;
29 static WINDOW *VIEW, *BORDER;
30 
31 BOOL inhex=TRUE;
32 BOOL inedit=FALSE;
33 BOOL hexoffset=TRUE;
34 
35 
36 #define CURSOR_CALC_X (10+((cursor_pos_x<(BYTES))? 2:3)+(cursor_pos_x)+(cursor_pos_x/2))
37 #define CURSOR_POS_X ((inhex)? CURSOR_CALC_X:(WCOLS-BYTES+cursor_pos_x))
38 #define C_POSX (((cursor_pos_x%2)!=1)? cursor_pos_x:(cursor_pos_x-1))
39 #define CURSOR_POSX ((inhex)? (C_POSX/2):cursor_pos_x)
40 #define CANTX(x) ((inhex)? (x*2):x)
41 #define THECOLOR ((inedit)? COLOR_PAIR(STATS_COLOR):COLOR_PAIR(DIR_COLOR))
42 
43 static int ViewFile(DirEntry * dir_entry, char *file_path);
44 static int ViewArchiveFile(char *file_path);
45 
46 
47 
View(DirEntry * dir_entry,char * file_path)48 int View(DirEntry * dir_entry, char *file_path)
49 {
50   switch( mode )
51   {
52     case DISK_MODE :
53     case USER_MODE :     return( ViewFile(dir_entry, file_path ) );
54     case TAPE_MODE:
55     case RAR_FILE_MODE:
56     case RPM_FILE_MODE:
57     case TAR_FILE_MODE :
58     case ZOO_FILE_MODE :
59     case ZIP_FILE_MODE :
60     case LHA_FILE_MODE :
61     case ARC_FILE_MODE : return( ViewArchiveFile( file_path ) );
62     default:             beep(); return( -1 );
63   }
64 }
65 
66 
67 
ViewFile(DirEntry * dir_entry,char * file_path)68 static int ViewFile(DirEntry * dir_entry, char *file_path)
69 {
70   char *command_line, *aux;
71   int  compress_method;
72   int  result = -1;
73   char *file_p_aux;
74   BOOL notice_mapped = FALSE;
75   char cwd[PATH_LENGTH+1];
76   char path[PATH_LENGTH+1];
77 
78   command_line = file_p_aux = NULL;
79 
80   if( ( file_p_aux = (char *) malloc( COMMAND_LINE_LENGTH + 1 ) ) == NULL )
81   {
82     ERROR_MSG( "Malloc failed*ABORT" );
83     exit( 1 );
84   }
85   StrCp(file_p_aux, file_path);
86 
87   if( access( file_path, R_OK ) )
88   {
89     (void) sprintf( message,
90 		    "View not possible!*\"%s\"*%s",
91 		    file_path,
92 		    strerror(errno)
93 		  );
94     MESSAGE( message );
95     ESCAPE;
96   }
97 
98   if( ( command_line = malloc( COMMAND_LINE_LENGTH + 1 ) ) == NULL )
99   {
100     ERROR_MSG( "Malloc failed*ABORT" );
101     exit( 1 );
102   }
103 
104   if (( aux = GetExtViewer(file_path))!= NULL)
105   {
106      if (strstr(aux,"%s") != NULL)
107      {
108         (void) sprintf(command_line, aux, file_p_aux);
109      }
110      else
111           (void) sprintf(command_line, "%s %s", aux, file_p_aux);
112   }
113   else
114   {
115     compress_method = GetFileMethod( file_path );
116     if( compress_method == FREEZE_COMPRESS )
117     {
118       (void) sprintf( command_line,
119 		      "%s < %s %s | %s",
120 		      MELT,
121 		      file_p_aux,
122 		      ERR_TO_STDOUT,
123 		      PAGER
124 		    );
125   }
126   else if( compress_method == COMPRESS_COMPRESS )
127   {
128     (void) sprintf( command_line,
129 		    "%s < %s %s | %s",
130 		    UNCOMPRESS,
131 		    file_p_aux,
132 		    ERR_TO_STDOUT,
133 		    PAGER
134 		  );
135   }
136   else if( compress_method == GZIP_COMPRESS )
137   {
138     (void) sprintf( command_line,
139                     "%s < %s %s | %s",
140 		    GNUUNZIP,
141 		    file_p_aux,
142 		    ERR_TO_STDOUT,
143 		    PAGER
144 		  );
145   }
146   else if( compress_method == BZIP_COMPRESS )
147   {
148     (void) sprintf( command_line,
149                     "%s < %s %s | %s",
150 		    BUNZIP,
151 		    file_p_aux,
152 		    ERR_TO_STDOUT,
153 		    PAGER
154 		  );
155   }
156   else
157   {
158     (void) sprintf( command_line,
159 		    "%s %s",
160 		    PAGER,
161 		    file_p_aux
162 		  );
163   }
164   }
165 
166 /* --crb3 01oct02: replicating what I did to <e>dit, eliminate
167 the problem with jstar-chained-thru-less writing new files to
168 the ytree starting cwd. new code grabbed from execute.c.
169 */
170 
171 
172   if (mode == DISK_MODE)
173   {
174   	if (Getcwd(cwd, PATH_LENGTH) == NULL)
175   	{
176   		WARNING("Getcwd failed*\".\"assumed");
177   		(void) strcpy(cwd, ".");
178   	}
179   	if (chdir(GetPath(dir_entry, path)))
180   	{
181   		(void) sprintf(message, "Can't change directory to*\"%s\"", path);
182   		MESSAGE(message);
183   	}else{
184   		result = SystemCall(command_line);
185   	}
186   	if( chdir(cwd) )
187 	{
188   		(void) sprintf(message, "Can't change directory to*\"%s\"", cwd);
189   		MESSAGE(message);
190 	}
191   }else{
192   	result = SystemCall(command_line);
193   }
194 
195   /*  if((result = SilentSystemCall( command_line )))   ..did systemcall just above */
196   if(result)
197   {
198     (void) sprintf( message, "can't execute*%s", command_line );
199     MESSAGE( message );
200   }
201 
202   if( notice_mapped )
203   {
204     UnmapNoticeWindow();
205   }
206 
207 FNC_XIT:
208 
209   if(file_p_aux)
210     free(file_p_aux);
211   if(command_line)
212     free(command_line);
213 
214   return( result );
215 }
216 
217 
218 
ViewArchiveFile(char * file_path)219 static int ViewArchiveFile(char *file_path)
220 {
221   char *command_line, *aux;
222   char buffer[100];
223   char *archive;
224   int  result = -1;
225 
226   if( ( command_line = malloc( COMMAND_LINE_LENGTH + 1 ) ) == NULL )
227   {
228     ERROR_MSG( "Malloc failed*ABORT" );
229     exit( 1 );
230   }
231 
232   if (( aux = GetExtViewer(file_path)) != NULL) {
233      if (strstr(aux,"%s") != NULL) {
234   	(void) sprintf( buffer, "| %s", PAGER );
235      } else {
236   	(void) sprintf( buffer, "| %s", aux ); /* maybe pipe-able */
237      }
238   } else {
239     (void) sprintf( buffer, "| %s", PAGER );
240   }
241 
242   archive = (mode == TAPE_MODE) ? statistic.tape_name : statistic.login_path;
243 
244   MakeExtractCommandLine( command_line,
245 			  archive,
246 			  file_path,
247 			  buffer
248 			);
249   if((result = SystemCall( command_line )))
250   {
251     (void) sprintf( message, "can't execute*%s", command_line );
252     MESSAGE( message );
253   }
254 
255   free( command_line );
256 
257   return( result );
258 }
259 
260 
261 
strn2print(char * dest,char * src,int c)262 char *strn2print(char *dest, char *src, int c)
263 {
264     dest[c]='\0';
265     for( ;c >= 0;c--)
266 	dest[c] = (isprint(src[c]) ? src[c] : '.');
267     return dest;
268 }
269 
270 
printhexline(WINDOW * win,char * line,char * buf,int r,long offset)271 void printhexline(WINDOW *win, char *line, char *buf, int r, long offset)
272 {
273     char *aux;
274     int i;
275     aux = (char *) xmalloc(WCOLS );
276     if (r==0)
277     {
278 	wclrtoeol(win);
279 	return;
280     }
281     if(hexoffset) {
282       sprintf(line, "%010X  ", (int)offset);
283     } else {
284       sprintf(line, "%010d  ", (int)offset);
285     }
286     for (i = 1; i <= r; i++ )
287     {
288         if ((i == (BYTES / 2) ) || (i == BYTES ))
289 	    sprintf(aux, "%02hhX  ", buf[i-1]);
290         else
291 	    sprintf(aux, "%02hhX ", buf[i-1]);
292         strcat(line, aux);
293     }
294     for (i = r+1; i <= BYTES; i++)
295     {
296         buf[i-1]= ' ';
297         if ((i == (BYTES / 2) ) || (i == BYTES ))
298 	    sprintf(aux, "    ");
299         else
300 	    sprintf(aux, "   ");
301         strcat(line, aux);
302     }
303 /*    strcat(line, " ");*/
304     line[strlen(line)] = ' ';
305     for (i=0; i< WCOLS-BYTES; i++)
306 	waddch(win, line[i]| THECOLOR);
307     for( i=0; i< BYTES; i++)
308 	isprint(buf[i]) ? waddch(win, buf[i] | THECOLOR) :
309 			  waddch(win, ACS_BLOCK | COLOR_PAIR(HIDIR_COLOR));
310     free(aux);
311     return;
312 }
313 
update_line(WINDOW * win,long line)314 void update_line(WINDOW *win, long line)
315 {
316     int r;
317     char *buf;
318     char *line_string;
319     char mensaje[50];
320 
321     line_string = (char *) xmalloc(WCOLS);
322     memset(line_string, ' ', WCOLS);
323     line_string[0] = '\0';
324     buf = (char *) xmalloc(BYTES);
325     memset(buf, ' ', BYTES);
326     if (lseek(fd, (line - 1) * BYTES, SEEK_SET)== -1 )
327     {
328         sprintf(mensaje, "Error %ld ", line);
329 	perror(mensaje);
330 	fflush(stdout);
331 	return;
332     }
333     r = read(fd, buf, BYTES);
334     printhexline(win, line_string, buf, r, (line - 1) * (BYTES));
335     xfree(line_string);
336     xfree(buf);
337 }
338 
scroll_down(WINDOW * win)339 void scroll_down(WINDOW *win)
340 {
341     scrollok(win,TRUE);
342     wscrl(win,1);
343     scrollok(win,FALSE);
344     wmove(win, WLINES - 1 , 0);
345     update_line(win, current_line + WLINES - 1);
346     wnoutrefresh(win);
347     doupdate();
348 }
349 
scroll_up(WINDOW * win)350 void scroll_up(WINDOW *win)
351 {
352     scrollok(win,TRUE);
353     wscrl(win,-1);
354     scrollok(win,FALSE);
355     wmove(win, 0, 0);
356     update_line(win, current_line );
357     wnoutrefresh(win);
358     doupdate();
359 }
360 
update_all_lines(WINDOW * win,char l)361 void update_all_lines(WINDOW *win, char l)
362 {
363     long i;
364 
365     for (i = current_line; i <= current_line + l; i++)
366     {
367 	wmove(win, i - current_line, 0);
368 	update_line(win, i);
369     }
370     wnoutrefresh(win);
371     doupdate();
372 }
373 
374 
Change2Edit(char * file_path)375 void Change2Edit(char *file_path)
376 {
377     int i;
378     char *str;
379 
380     str = (char *)xmalloc(COLS);
381 
382     for(i = WLINES + 4; i < LINES; i++)
383     {
384 	wmove(stdscr,i , 0);
385 	wclrtoeol(stdscr);
386     }
387     doupdate();
388 
389     Print( stdscr, 0, 0, "File: ", MENU_COLOR );
390     Print( stdscr, 0, 6, CutPathname(str,file_path,WCOLS-5), HIMENUS_COLOR );
391     PrintOptions( stdscr, LINES - 3, 0, "(Edit file in hexadecimal mode)");
392     PrintOptions( stdscr, LINES - 2, 0, "(Q)uit   (^L) redraw  (<TAB>) change edit mode");
393     PrintOptions( stdscr, LINES - 1, 0,
394 		"(NEXT)-(RIGHT)/(PREV)-(LEFT) page   (HOME)-(END) of line   (DOWN)-(UP) line");
395     free(str);
396     return;
397 }
398 
Change2View(char * file_path)399 void Change2View(char *file_path)
400 {
401     int i;
402     char *str;
403 
404     str = (char *)xmalloc(COLS);
405     for(i = WLINES + 4; i < LINES; i++)
406     {
407 	wmove(stdscr,i , 0);
408 	wclrtoeol(stdscr);
409     }
410     doupdate();
411 
412     Print( stdscr, 0, 0, "File: ", MENU_COLOR );
413     Print( stdscr, 0, 6, CutPathname(str,file_path,WCOLS-5), HIMENUS_COLOR );
414     PrintOptions( stdscr, LINES - 3, 0, "View file in hexadecimal mode");
415     PrintOptions( stdscr, LINES - 2, 0, "(Q)uit   (^L) redraw  (E)dit hex");
416     PrintOptions( stdscr, LINES - 1, 0,
417 		"(NEXT)-(RIGHT)/(PREV)-(LEFT) page   (HOME)-(END) of line   (DOWN)-(UP) line");
418     free(str);
419     return;
420 }
421 
SetupViewWindow(char * file_path)422 void SetupViewWindow(char *file_path)
423 {
424     int i;
425     char *str;
426 
427     str = (char *)xmalloc(COLS);
428     WLINES= LINES - 6;
429     WCOLS= COLS - 2;
430     if (BORDER)
431 	delwin(BORDER);
432     BORDER=newwin(WLINES + 2, WCOLS + 2, 1, 0);
433     if (VIEW)
434 	delwin(VIEW);
435     VIEW=newwin(WLINES, WCOLS, 2, 1);
436     keypad(VIEW,TRUE);
437     scrollok(VIEW,FALSE);
438     clearok(VIEW,TRUE);
439     leaveok(VIEW,FALSE);
440 /*    werase(VIEW);*/
441     WbkgdSet(VIEW,COLOR_PAIR(WINDIR_COLOR));
442     wclear(VIEW);
443     for( i = 0; i < WLINES - 1; i++)
444     {
445 	wmove(VIEW,i,0);
446 	wclrtoeol(VIEW);
447     }
448     WbkgdSet(BORDER,COLOR_PAIR(WINDIR_COLOR)|A_BOLD);
449     box(BORDER,0,0);
450     RefreshWindow(BORDER);
451     RefreshWindow(VIEW);
452     Change2View(file_path);
453     BYTES = (WCOLS - 13) / 4;
454     free(str);
455     return;
456 
457 }
458 
459 
460 
hexval(unsigned char v)461 unsigned char hexval(unsigned char v) {
462 	if (v >= 'a' && v <= 'f')
463 		v = v - 'a' + 10;
464 	else if (v >= '0' && v <= '9')
465 		v = v - '0';
466 	return v;
467 }
468 
469 
change_char(int ch)470 void change_char(int ch)
471 {
472 
473     CHANGES *cambio=NULL;
474     char pp=0;
475     char mensaje[50];
476 
477     cambio = malloc(sizeof(struct MODIF));
478     cambio -> pos = ( (cursor_pos_y + current_line - 1) * BYTES) + CURSOR_POSX;
479     if (lseek(fd, cambio -> pos, SEEK_SET)== -1 )
480     {
481         sprintf(mensaje,"Error %s ", strerror(errno));
482 	perror(mensaje);
483 	fflush(stdout);
484 	free(cambio);
485 	return;
486     }
487     if ((read(fd, &cambio -> old_char,1)==1))
488 
489     if (lseek(fd, cambio -> pos, SEEK_SET)!= -1 )
490     {
491 	if (inhex) {
492 	    switch( ch){
493 	    case '0': case '1': case '2': case '3': case '4':
494 	    case '5': case '6': case '7': case '8': case '9':
495 	    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
496 	    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
497 		if ((cursor_pos_x%2)==1)
498 		    pp = (cambio -> old_char & 0xF0) | (hexval(ch));
499 		else
500 		    pp = (cambio -> old_char & 0x0F) | (hexval(ch) << 4);
501 		touchwin(VIEW);
502 		break;
503 	    default:
504 		beep();
505 		touchwin(VIEW);
506 		free(cambio);
507 		return;
508 		break;
509 	    }
510 	}else{
511 	    pp = ch;
512 	}
513     	if (write(fd, &pp, 1)!= 1)
514 	{
515     	    sprintf(mensaje,"Error al grabar el cambio %s ", strerror(errno));
516 	    perror(mensaje);
517 	    fflush(stdout);
518 	    free(cambio);
519 	    return;
520 	}
521 	cambio -> new_char = pp;
522 	cambio -> next = changes;
523 	changes = cambio;
524     }else{
525         sprintf(mensaje,"Error al posicionar %s ", strerror(errno));
526         perror(mensaje);
527         fflush(stdout);
528         free(cambio);
529         return;
530     }
531     else{
532         sprintf(mensaje,"Error al pre-leer %s ", strerror(errno));
533         perror(mensaje);
534         fflush(stdout);
535         free(cambio);
536         return;
537     }
538     return;
539 }
540 
541 
move_right(WINDOW * win)542 void move_right(WINDOW *win)
543 {
544    fstat(fd,&fdstat);
545    cursor_pos_x++;
546    if (fdstat.st_size > ((cursor_pos_y+current_line-1) * BYTES + CURSOR_POSX )){
547 	cursor_pos_x--;
548 	if ( cursor_pos_x < CANTX(BYTES) - 1 ) {
549     	    cursor_pos_x += 1;
550 	    wmove( win, cursor_pos_y, CURSOR_POS_X);
551 	}else {
552 	    if (fdstat.st_size >= ((current_line+cursor_pos_y) * BYTES) ){
553 		if (cursor_pos_y < WLINES-1 ) {
554 		    cursor_pos_y++;
555 		    cursor_pos_x = 0;
556 		    wmove( win, cursor_pos_y, CURSOR_POS_X);
557 		} else {
558 		    current_line++;
559 		    scroll_down(win);
560 		    cursor_pos_x = 0;
561 		    wmove( win, cursor_pos_y, CURSOR_POS_X);
562 		}
563 	    } else
564 		beep();
565 	}
566     }else{
567 	cursor_pos_x--;
568 	beep();
569     }
570     return;
571 }
572 
hex_edit(char * file_path)573 void hex_edit(char *file_path)
574 {
575     int ch;
576     char mensaje[50];
577 
578     BOOL QUIT=FALSE;
579 
580     cursor_pos_x = cursor_pos_y = 0;
581     fd2 = fd;
582     fd=open(file_path,O_RDWR);
583     if (fd == -1){
584         sprintf(mensaje,"Error %s ", strerror(errno));
585 	ERROR_MSG(mensaje);
586 	touchwin(VIEW);
587         fd = fd2;
588 	return;
589     }
590     inedit=TRUE;
591     update_all_lines(VIEW,WLINES-1);
592     leaveok( VIEW, FALSE);
593     curs_set( 1);
594     wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
595     wnoutrefresh(VIEW);
596     while (!QUIT) {
597     doupdate();
598     ch = (resize_request) ? -1 : Getch();
599 #ifdef VI_KEYS
600 	ch = ViKey(ch);
601 #endif
602        if (resize_request)
603        {
604     	    SetupViewWindow(file_path);
605 	    Change2Edit(file_path);
606 /*	    current_line = oldpos/BYTES;*/
607 	    update_all_lines(VIEW,WLINES-1);
608 	    wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
609 	    wnoutrefresh(VIEW);
610 	    doupdate();
611 	}
612 
613 	switch(ch){
614 	    case ESC: QUIT=TRUE;
615 		      break;
616 	    case KEY_DOWN: /*ScrollDown();*/
617 			   fstat(fd,&fdstat);
618 			   if (fdstat.st_size > ((cursor_pos_y + current_line - 1) * BYTES + CURSOR_POSX)) {
619 
620 			   	if (fdstat.st_size > ((cursor_pos_y + current_line - 1 + 1) * BYTES + CURSOR_POSX)) {
621 
622 					if (cursor_pos_y < WLINES-1){
623 				    		wmove( VIEW, ++cursor_pos_y, CURSOR_POS_X);
624 				    		wnoutrefresh(VIEW);
625 					} else {
626 				    		++current_line;
627 				    		scroll_down(VIEW);
628 				    		wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
629 				    		wnoutrefresh(VIEW);
630 					}
631 				} else {
632 					/* special case: last line */
633 
634 					if (fdstat.st_size > ((cursor_pos_y + current_line - 1 + 1) * BYTES)) {
635 
636 						for(cursor_pos_x = 0; (CURSOR_POSX + 1) < (fdstat.st_size % BYTES); cursor_pos_x++);
637 
638 						if (cursor_pos_y < WLINES-1){
639 							wmove( VIEW, ++cursor_pos_y, CURSOR_POS_X);
640 							wnoutrefresh(VIEW);
641 						} else {
642 							++current_line;
643 							scroll_down(VIEW);
644 							wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
645 							wnoutrefresh(VIEW);
646 						}
647 					}
648 				}
649 			    } else {
650 				beep();
651 			    }
652 			    break;
653 	    case KEY_UP: /*ScroollUp();*/
654 			if (cursor_pos_y > 0)
655 			{
656 			    wmove( VIEW, --cursor_pos_y, CURSOR_POS_X);
657     			    wnoutrefresh(VIEW);
658 			} else if (current_line > 1) {
659 			    current_line--;
660 			    scroll_up(VIEW);
661 			    wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
662     			    wnoutrefresh(VIEW);
663 			} else
664 			    beep();
665 	                break;
666 	    case KEY_LEFT: /* move 1 char left */
667 			    if ( cursor_pos_x > 0 ) {
668 			        cursor_pos_x-=1;
669 				wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
670 			    } else if (cursor_pos_y > 0 ) {
671 				/*cursor_pos_x=ultimo_caracter;*/
672 				cursor_pos_x=CANTX(BYTES) - 1;
673 				wmove( VIEW, --cursor_pos_y,CURSOR_POS_X);
674 			    } else if (current_line > 1) {
675 				current_line--;
676 				scroll_up(VIEW);
677 				cursor_pos_x=CANTX(BYTES) - 1;
678 				wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
679 			    } else
680 				beep();
681 			wnoutrefresh(VIEW);
682 			break;
683 	    case KEY_PPAGE: /*ScrollPageDown();*/
684 			    if (current_line > WLINES)
685 				current_line -= WLINES;
686 			    else
687 				if (current_line > 1)
688 				   current_line = 1;
689 				else
690 				    beep();
691 /*			    oldpos = current_line * BYTES;*/
692 			    update_all_lines(VIEW,WLINES);
693 			    wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
694 			    wnoutrefresh(VIEW);
695 			    break;
696 	    case KEY_RIGHT: move_right(VIEW);
697 			    wnoutrefresh(VIEW);
698 		            break;
699 	    case KEY_NPAGE: /*ScroollPageUp();*/
700 			    fstat(fd,&fdstat);
701 			    if (fdstat.st_size > ((current_line - 1 + WLINES + cursor_pos_y) * BYTES) + CURSOR_POSX ) {
702 				current_line += WLINES;
703 			    } else {
704 			        int n;
705 				n = fdstat.st_size / BYTES; /* numer of full lines */
706 				if(fdstat.st_size % BYTES) {
707 				  n++; /* plus 1 not fully used line */
708 				}
709 				if(current_line != n) {
710 				  current_line = n;
711 				  cursor_pos_y = 0;
712 				  for(cursor_pos_x = 0; (CURSOR_POSX + 1) < (fdstat.st_size % BYTES); cursor_pos_x++);
713 				} else {
714 				  beep();
715 				}
716 			    }
717 /*			    oldpos = current_line * BYTES;*/
718 			    update_all_lines(VIEW,WLINES);
719 			    wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
720 			    wnoutrefresh(VIEW);
721 		            break;
722 	    case KEY_HOME:
723 			    if (CURSOR_POSX > 0) {
724 				cursor_pos_x = 0;
725 				wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
726 			    } else
727 				beep();
728 			    wnoutrefresh(VIEW);
729 	                    break;
730 	    case KEY_END:
731 			 fstat(fd,&fdstat);
732 			 if ( ((cursor_pos_y + current_line) * BYTES) > fdstat.st_size ) {
733 			        cursor_pos_x = CANTX(fdstat.st_size % BYTES) - 1;
734 			 } else {
735 			    cursor_pos_x = CANTX(BYTES)-1;
736 			 }
737 			 wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
738 			 wnoutrefresh(VIEW);
739 	                 break;
740 	    case '\t' :
741 			/* move cursor to the the other part of the window*/
742 			if (inhex){
743 			    inhex=FALSE;
744 			    cursor_pos_x=cursor_pos_x/2;
745 			}else{
746 			    inhex=TRUE;
747 			    cursor_pos_x=cursor_pos_x*2;
748 			}
749 			wmove( VIEW, cursor_pos_y, CURSOR_POS_X);
750 			wnoutrefresh(VIEW);
751 			break;
752 	    case 'L' & 0x1f:
753 			clearok(stdscr,TRUE);
754 			RefreshWindow(stdscr);
755 			break;
756 
757 	    case 'q':
758 	    case 'Q': if (inhex) {
759 		        QUIT=TRUE;
760 			break;
761 			}
762 	    default:
763 		    change_char(ch);
764 		    wmove(VIEW, cursor_pos_y, 0);
765 		    update_line(VIEW, current_line+cursor_pos_y);
766 		    move_right(VIEW);
767 		    wmove(VIEW, cursor_pos_y, CURSOR_POS_X);
768 		    wnoutrefresh(VIEW);
769 		    break;
770 	}
771     }
772     curs_set( 0);
773     close(fd);
774     fd=fd2;
775     inedit=FALSE;
776     return;
777 }
778 
779 
InternalView(char * file_path)780 int InternalView(char *file_path)
781 {
782     long oldpos;
783     int ch;
784     BOOL QUIT=FALSE;
785 
786     hexoffset = (!strcmp(HEXEDITOFFSET, "HEX")) ? TRUE : FALSE;
787 
788     if (stat(file_path, &fdstat)!=0)
789 	return -1;
790     if (!(S_ISREG(fdstat.st_mode)) || S_ISBLK(fdstat.st_mode))
791 	return -1;
792     fd=open(file_path,O_RDONLY);
793     if (fd == -1)
794 	return -1;
795     SetupViewWindow(file_path);
796     current_line = 1;
797     oldpos = 1;
798     update_all_lines(VIEW,WLINES-1);
799     while (!QUIT) {
800     ch = (resize_request) ? -1 : Getch();
801 #ifdef VI_KEYS
802 	ch = ViKey(ch);
803 #endif
804        if (resize_request)
805        {
806     	    SetupViewWindow(file_path);
807 	    current_line = oldpos/BYTES;
808 	    update_all_lines(VIEW,WLINES-1);
809 	}
810 
811 	switch(ch){
812 	    case ESC:
813 	    case 'q':
814 	    case 'Q': QUIT=TRUE;
815 		      break;
816 	    case 'e':
817 	    case 'E': Change2Edit(file_path);
818 	    	      hex_edit(file_path);
819 		      update_all_lines(VIEW,WLINES-1);
820 		      Change2View(file_path);
821 		      break;
822 	    case KEY_DOWN: /*ScrollDown();*/
823 			   fstat(fd,&fdstat);
824 			   if (fdstat.st_size > (current_line * BYTES) )
825 			   {
826 				current_line++;
827 				oldpos = current_line * BYTES;
828 				scroll_down(VIEW);
829 			    }
830 			    else
831 				beep();
832 			    break;
833 	    case KEY_UP: /*ScroollUp();*/
834 			if (current_line > 1)
835 			{
836 			    current_line--;
837 			    oldpos = current_line * BYTES;
838 			    scroll_up(VIEW);
839 			}
840 			else
841 			    beep();
842 	                break;
843 	    case KEY_LEFT:
844 	    case KEY_PPAGE: /*ScrollPageDown();*/
845 			    if (current_line > WLINES)
846 				current_line -= WLINES;
847 			    else
848 				if (current_line > 1)
849 				   current_line = 1;
850 				else
851 				    beep();
852 			    oldpos = current_line * BYTES;
853 			    update_all_lines(VIEW,WLINES);
854 			    break;
855 	    case KEY_RIGHT:
856 	    case KEY_NPAGE: /*ScroollPageUp();*/
857 			    fstat(fd,&fdstat);
858 			    if (fdstat.st_size > ((current_line - 1 + WLINES) * BYTES) ) {
859 				current_line += WLINES;
860 			    } else {
861 			        int n;
862 				n = fdstat.st_size / BYTES; /* numer of full lines */
863 				if(fdstat.st_size % BYTES) {
864 				  n++; /* plus 1 not fully used line */
865 				}
866 				if(current_line != n) {
867 				  current_line = n;
868 				} else {
869 				  beep();
870 				}
871 			    }
872 			    oldpos = current_line * BYTES;
873 			    update_all_lines(VIEW,WLINES);
874 		            break;
875 	    case KEY_HOME: /*ScrollHome();*/
876 			    if (current_line > 1)
877 			    {
878 				current_line = 1;
879 				oldpos = current_line * BYTES;
880 				update_all_lines(VIEW,WLINES-1);
881 			    }else
882 				beep();
883 	                    break;
884 	    case KEY_END: /*ScrollEnd();*/
885 			 fstat(fd,&fdstat);
886 			 if (fdstat.st_size >= BYTES * 2)
887 			    current_line = (fdstat.st_size - BYTES) / BYTES;
888 			 else
889 			    beep();
890 			oldpos = current_line * BYTES;
891 			update_all_lines(VIEW,WLINES);
892 	                break;
893 	    case 'L' & 0x1f:
894 			clearok(stdscr,TRUE);
895 			RefreshWindow(stdscr);
896 			break;
897 	    default: break;
898 	}
899     }
900     Print( stdscr, 0, 0, "Path: ", MENU_COLOR );
901     delwin(VIEW);
902     delwin(BORDER);
903     touchwin(stdscr);
904     wnoutrefresh(stdscr);
905     close(fd);
906     return 0;
907 }
908