home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / educatio / xcoral16.zip / GET_FILE.C < prev    next >
C/C++ Source or Header  |  1993-01-15  |  19KB  |  783 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/cursorfont.h>
  18. #include <X11/Xutil.h>
  19. #include <X11/keysym.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <sys/file.h>
  23. #include <sys/param.h>
  24. #include <malloc.h>
  25. #include <string.h> 
  26.  
  27. #include <errno.h>
  28.  
  29. #include "m_key.h"
  30. #include "menus.h"
  31. #include "buttons.h"
  32. #include "scroll.h"
  33. #include "text.h"
  34. #include "browser.h"
  35. #include "flist.h"
  36.  
  37. #ifdef sun
  38. #define _SUN_OS
  39. #include <sys/exec.h>
  40. #define ISMAG(x) (((x) == OMAGIC) || ((x) == NMAGIC) || ((x) == ZMAGIC))
  41. #endif
  42.  
  43. #if  (m68k && _AUX_SOURCE)
  44. #define _APPLE_A_UX
  45. #include <filehdr.h>
  46. #define ISMAG(x) (((x)==MC68MAGIC) || ((x)==MC68TVMAGIC) || ((x)==M68MAGIC) || ((x)==M68TVMAGIC) \
  47. || ((x)==M68NSMAGIC))
  48. #endif
  49.  
  50. #ifdef hpux
  51. #define _HPUX
  52. #include <filehdr.h>
  53. #define ISMAG(x) (((x) == RELOC_MAGIC) || ((x) == EXEC_MAGIC) || ((x) == SHARE_MAGIC) \
  54.     || ((x) == DEMAND_MAGIC) || ((x) == DL_MAGIC) || ((x) == SHL_MAGIC))
  55. #endif
  56.  
  57. #if ((ultrix) && (mips))
  58. #define _DEC_ULTRIX
  59. #include <sys/exec.h>
  60. #define ISMAG(x) (((x) == OMAGIC) || ((x) == NMAGIC) || ((x) == ZMAGIC))
  61. #endif
  62.  
  63. #ifndef ISMAG
  64. #define _BAD_SYS
  65. #define ISMAG(x) (((x) == OMAGIC) || ((x) == NMAGIC) || ((x) == ZMAGIC))
  66. #endif
  67.  
  68. extern char *GetString (), *GetStringFromDialogBox ();
  69. extern     Display    *dpy;
  70. static int CheckFile (), IsBinary ();
  71. static void WriteFile ();
  72.  
  73. /*
  74. **    Function name : KbdReadFile
  75. **
  76. **    Description : Commande 'read file' a partir du clavier.
  77. **    Input : Le text courant.
  78. **    Ouput :
  79. */
  80. void KbdReadFile ( text )
  81. Text *text;
  82. {
  83.     register char *str; 
  84.          Text *result;
  85.     char c = '\007'; /* ^G */
  86.  
  87.     if ( GetModif ( text ) == True ) {
  88.               if ( SaveCurrentBuffer ( text, F_KEY ) != True )
  89.                   return;
  90.     }
  91.     ClearMessageWindow ( text -> mwin );
  92.  
  93.     str = GetString ( text, "Read File : ", (char *) 0 );
  94.  
  95.     if ( (str == NULL) || (strncmp(str, &c, 1)) == NULL ) {
  96.         DisplayMessage ( text -> mwin, "Abort" );
  97.         return;
  98.     }
  99.     TextCursorOff ( text );
  100.     if ( LoadFile ( text, str, NEW ) != -1 ) {
  101.         ShowScrollFrame ( dpy, text -> swin );
  102.         FirstPage ( text );
  103.         SetTextSave ( text );
  104.         if ( IsAlreadyLoad ( text -> filename, &result ) > 1 ) {
  105.             XBell ( dpy, 10 );
  106.             DisplayMessage ( text -> mwin, "Warning ...Already loaded" );
  107.         }
  108.     }
  109.     TextCursorOn ( text );
  110. }
  111.  
  112.  
  113. /*
  114. **    Function name : KbdInsertFile
  115. **
  116. **    Description : Commande 'insert file' a partir du clavier.
  117. **    Input : 
  118. **    Ouput :
  119. */
  120. void KbdInsertFile ( text )
  121. Text *text;
  122. {
  123.     register char *str;
  124.     char c = '\007'; /* ^G */
  125.  
  126.        ClearMessageWindow ( text -> mwin );
  127.     
  128.     str = GetString ( text, "Insert File : ", (char *) 0 );
  129.         
  130.     if ( (str == NULL) || (strncmp(str, &c, 1)) == NULL ) {
  131.         DisplayMessage ( text -> mwin, "Abort" );
  132.         return;
  133.     }
  134.  
  135.     TextCursorOff ( text );
  136.     if ( LoadFile ( text, str,  INSERT ) != -1 ) {
  137.         SetTextModif ( text );        
  138.         SetAndDisplayPage ( text ); 
  139.         ShowScrollFrame ( dpy, text -> swin );
  140.         (void) MoveScrollBar ( dpy, text -> swin, 
  141.             CURRENT, text -> no_current_line - text -> n1 - 1 );
  142.     }
  143.     TextCursorOn ( text );
  144. }
  145.  
  146.  
  147. /*
  148. **    Function name : LoadFile
  149. **
  150. **    Description : Charge un fichier.
  151. **    Input : Le text courant, le nom du fichier, type de
  152. **        l'operation ( nouveau ou insert ).
  153. **    Ouput : 0 si OK -1 sinon
  154. */
  155. int LoadFile ( text, s, type )
  156.     Text *text;
  157.     register char *s;
  158.     register int type;
  159. {
  160.     static int len;
  161.     register int n;
  162.     Text *result;
  163.     FILE *fd;
  164. #ifdef DEBUG
  165.     (void) fprintf ( stderr, "filename = %s\n", s );
  166. #endif DEBUG
  167.     if ( CheckFile ( s, &len, text ) == NULL ) {
  168.         fd = fopen ( s, "r" );
  169.         if ( fd == NULL ) {
  170.             (void) fprintf ( stderr, "Open error\n" );
  171.             return -1;
  172.         }
  173.         if ( IsBinary ( fd, text ) == False ) {
  174.             (void) fclose ( fd );
  175.             return -1;
  176.         }
  177.         rewind ( fd );
  178.         switch ( type ) {
  179.         case NEW:
  180.             (void) LoadFileInBuffer ( text -> buf, fd, len, NEW );
  181.             SetDirAndFilename ( text, s );
  182.             XStoreName ( dpy,  text ->  w_parent, text -> filename ); 
  183.             break;
  184.         case INSERT:
  185.             (void) LoadFileInBuffer ( text -> buf, fd, len,  INSERT );
  186.             break;
  187.         }
  188.         n = GetNumberOfLineInBuf ( text -> buf );
  189. #ifdef DEBUG
  190.     (void) fprintf ( stderr, "n = %d\n", n );
  191. #endif
  192.         text -> lines_in_buf = n;
  193.         SetScrollLine ( text -> swin, n );
  194.         (void) fclose ( fd );
  195.         return 0;
  196.     }
  197.     else
  198.         return -1;
  199. }
  200.  
  201. /*
  202. **    Function name : SetDirFilename
  203. **
  204. **    Description : Positionne la directorie et le
  205. **        pathname complet.
  206. **    Input : Le text courant, le nom du fichier.
  207. **    Ouput :
  208. */
  209. void SetDirAndFilename ( text, name )
  210.     Text *text;
  211.     register char *name;
  212. {
  213.     register char *p = name;
  214.        register char *old_dir;
  215.        char pathname [ MAXPATHLEN ];
  216.     extern char  *getcwd();
  217.  
  218.     /*
  219.      * Ici, name est un nom de fichier valide. On doit utiliser le pathname
  220.      * complet a cause du browser. Plusieurs cas sont possibles :
  221.      * name commence par / 
  222.      */
  223.     old_dir = (char *) malloc ( (unsigned) strlen ( text -> current_dir ) + 2 );
  224.        (void) strcpy ( old_dir, text -> current_dir );
  225.    
  226.     if ( (p = strrchr ( name, '/' )) == 0 ) {  /* Nom de fichier de la directorie courante */
  227.         (void) sprintf ( text -> filename,"%s/%s", text -> current_dir, name );
  228.     }
  229.     else if ( (p - name) == 0 ) { /* On doit aller dans la racine */
  230.         (void) chdir ( "/" );
  231.         (void) strcpy ( text -> current_dir, "/" );
  232.         (void) sprintf ( text -> filename,"%s", name );
  233.     }
  234.     else {    /* Ya 1 ou plusieurs '/' */
  235.               if ( *name == '/' ) {
  236.                      (void) strncpy ( text -> current_dir, name, ( p - name ));
  237.             text -> current_dir [p - name] = '\0';
  238.                }
  239.               else {
  240.                    (void) strncat ( text -> current_dir, "/", 1);
  241.             (void) strncat ( text -> current_dir, name, ( p - name ));
  242.                }
  243.         (void) sprintf ( text -> filename, "%s/%s", text -> current_dir, (char *) (p + 1) );
  244.         }
  245.     if ( strcmp ( old_dir, text -> current_dir ) != 0 ) {
  246.               (void) chdir ( text -> current_dir );
  247.            /*
  248.             * A cause de l'automount et des liens symboliques il faut
  249.             * de nouveau verifier le path.
  250.             */
  251.            (void) getcwd ( pathname, MAXPATHLEN + 2 );
  252.            if ( strcmp ( pathname, text -> current_dir ) != 0 ) {
  253.                   (void) strcpy ( text -> current_dir, pathname );
  254.                   (void) sprintf ( text -> filename, "%s/%s",
  255.                          text -> current_dir, (char *) (p + 1) );
  256.             }
  257.           }
  258. #ifdef DEBUG      
  259.     printf ( "dirname = %s\n", text -> current_dir );
  260.           printf ( "filename = %s\n", text -> filename );
  261. #endif DEBUG
  262.     if ( old_dir != 0 )
  263.         (void) free ( old_dir );
  264.        return;
  265. }
  266.  
  267.  
  268. /*
  269. **    Function name : KbdSaveFile
  270. **
  271. **    Description : Commande 'save file' a partir du clavier.
  272. **    Input : Le text courant.
  273. **    Ouput :
  274. */
  275. void KbdSaveFile ( text )
  276.     Text *text;
  277. {
  278.     register char   *name;
  279.     char c = '\007';
  280.  
  281.     if ( strcmp (text -> filename, "NoName") == NULL ) {
  282.         name = GetString ( text, "Write file : ", (char *) 0 );
  283.         if ( (name == NULL) || strncmp(name, &c,1) == NULL ) {
  284.             DisplayMessage ( text -> mwin, "Abort" );
  285.             return;
  286.         }
  287.         else {
  288.             if ( *name == '/' ) {
  289.                 (void) strcpy ( text -> filename, name );
  290.             }
  291.             else {
  292.                 (void) strcpy ( text -> filename,  text -> current_dir );
  293.                 (void) strcat ( text -> filename, "/" );
  294.                 (void) strcat ( text -> filename, name );
  295.             }
  296.             (void) WriteFile ( text );
  297.         }
  298.     }
  299.     else {
  300. #ifdef DEBUG
  301.         (void) sprintf ( buf, "cp %s '#%s'\n",
  302.         text -> filename, text -> filename );
  303.         system ( buf );
  304. #endif DEBUG
  305.         if ( text -> modif == True )
  306.             (void) WriteFile ( text );
  307.         else 
  308.             DisplayMessage ( text -> mwin, "No changes" );    
  309.     }
  310. }
  311.  
  312.  
  313. /*
  314. **    Function name : WriteFile
  315. **
  316. **    Description : Ecriture du buffer courant dans un fichier.
  317. **    Input : Le text courant.
  318. **    Ouput :
  319. */
  320. static void WriteFile ( text )
  321.     Text *text;
  322. {
  323.     FILE *fd;
  324.     register int size;
  325.     extern char *sys_errlist[]; 
  326.     char buf [128];
  327.     register char *name;
  328.  
  329.     if ( (fd = fopen ( text -> filename, "w" )) == NULL ) {
  330.         DisplayMessage ( text -> mwin, sys_errlist[errno] );
  331.         return;
  332.     }
  333.     DisplayMessage ( text -> mwin, "Write ..." );
  334.        XSync ( dpy, False );
  335.     size = WriteCurrentFile ( text -> buf, fd );
  336.     if ( size == -1 )  {
  337.         (void) sprintf ( buf, "Write error" );
  338.         DisplayMessage ( text -> mwin, buf );
  339.               (void) fclose ( fd );
  340.               return;
  341.     }
  342.     else {
  343.         name = 0;
  344.         if ( (name = (char * ) strrchr ( text -> filename, '/' )) != 0 )
  345.             (void) sprintf ( buf, "Write %s, %d bytes.\n", ++name, size );
  346.         else {
  347.             (void) sprintf ( buf, "Write %s, %d bytes.\n", text -> filename, size );
  348.         }
  349.         DisplayMessage ( text -> mwin, buf );
  350.         SetTextSave ( text );
  351.     }
  352.     (void) fclose ( fd );
  353.        if ( (text -> filename != 0) && strlen ( text -> filename) != 0 ) {
  354.               if ( GoodSuffix ( text -> filename ) == True ) {
  355. #ifdef DEBUG
  356.     (void) fprintf ( stderr, "touch %s\n", text -> filename ); 
  357. #endif DEBUG
  358.             parse_file ( text -> filename ); 
  359.             RefreshBrowserInfos ();
  360.             TextCursorOff ( text );
  361.             TextCursorOn ( text );
  362.         }
  363.     }
  364. }
  365.  
  366.  
  367. /*
  368. **    Function name : KbdWriteFile
  369. **
  370. **    Description : Commande 'write file' a partir du clavier.
  371. **    Input : Le text courant.
  372. **    Ouput :
  373. */
  374. void KbdWriteFile ( text )
  375.     Text *text;
  376. {
  377.     register char *s;
  378.     char buf [128];
  379.     char c = '\007';
  380.     char *name;
  381.  
  382. #ifdef DEBUG
  383.     (void) fprintf ( stderr, "Write File from key\n" );
  384. #endif DEBUG
  385.  
  386.     if ( (name = (char * ) strrchr ( text -> filename, '/' )) != 0 )
  387.         (void) sprintf ( buf, "Write file [%s]  : ", ++name );
  388.     else
  389.         (void) sprintf ( buf, "Write file [%s]  : ", text -> filename );    
  390.  
  391.     s = GetString ( text, buf, (char *) 0 );
  392.     if ( (s == NULL) || (strncmp(s,"y",1) == NULL) ) {
  393.         WriteFile ( text );
  394.     }
  395.     else if ( (strncmp(s,"n",1 ) == NULL) || (strncmp(s,&c,1)==NULL) ) {
  396.         DisplayMessage ( text -> mwin, "Abort" );
  397.     }
  398.     else {
  399.         if ( *s == '/' ) {
  400.             (void) strcpy ( text -> filename, s );
  401.         }
  402.         else {
  403.             (void) strcpy ( text -> filename,  text -> current_dir );
  404.             (void) strcat ( text -> filename, "/" );
  405.             (void) strcat ( text -> filename, s );
  406.         }
  407.         WriteFile ( text );
  408.               XStoreName ( dpy, text ->  w_parent, text -> filename );
  409.     }
  410. }
  411.  
  412.  
  413. /*
  414. **    Function name : CheckFile
  415. **
  416. **    Description : Quelles les permissions sur le fichier.
  417. **    Input : Le pathname, la longueur, le text courant.
  418. **    Ouput : 0 Ok -1 sinon
  419. */
  420. static int CheckFile ( path, len, text )
  421.     char *path;
  422.     int *len;    /* RETURN */
  423.     Text *text;
  424. {
  425.     struct stat st;
  426.  
  427.     (void) stat ( path, &st );
  428.     if ( access ( path, F_OK ) != NULL ) {
  429.         DisplayMessage  ( text -> mwin, "File not found" );
  430.         return (-1);
  431.     }
  432.     if ( access ( path, R_OK ) != NULL ) {
  433.         DisplayMessage ( text -> mwin, "Permission denied" );
  434.         return (-1);
  435.     }
  436.     if ( access ( path, W_OK ) != NULL ) {
  437.         DisplayMessage ( text -> mwin, "Read only file" );
  438.     }
  439.     if ( ! S_ISREG(st.st_mode) ) {
  440.         DisplayMessage  ( text -> mwin, "Not a regular file" );
  441.         return (-1);
  442.     }
  443.  
  444.     *len = (int) st.st_size;
  445.     return NULL;
  446. }
  447.  
  448. /*
  449. **    Function name : IsBinary
  450. **
  451. **    Description : On verifie que le fichier n'est pas
  452. **        un binaire ou une archive.
  453. **    Input : Le stream associe, le text courant.
  454. **    Ouput : Vrai si binaire Faux sinon.
  455. */
  456. static int IsBinary ( fd, text )
  457.     FILE *fd;
  458.     Text *text;
  459. {
  460.        unsigned short magic;
  461. #ifdef _SUN_OS
  462.     struct exec head;
  463. #endif
  464. #ifdef _HPUX
  465.     struct header head;
  466. #endif
  467. #ifdef _DEC_ULTRIX
  468.     struct exec head;
  469. #endif
  470. #ifdef _APPLE_A_UX
  471.     struct filehdr head;
  472. #ifdef _BAD_SYS
  473.     struct exec head;
  474. #endif
  475. #endif
  476.     if ( read ( fileno(fd), (char *) &head, sizeof (head) ) < 0 ) {
  477.         (void) fprintf ( stderr, "Header read error\n" );
  478.         return False;
  479.     }
  480. #ifdef _SUN_OS
  481.     magic = head.a_magic;
  482. #endif
  483. #ifdef _DEC_ULTRIX
  484.     magic = head.ex_o.magic;
  485. #endif
  486. #ifdef _HPUX
  487.     magic = head.a_magic;
  488. #endif
  489. #ifdef _APPLE_A_UX
  490.     magic = head.f_magic;
  491. #endif
  492.     if ( ISMAG (magic) 
  493.         || (!strncmp ( (char *) &head, (char *) "!<arch>", 6)) ) {
  494.             DisplayMessage  ( text -> mwin, "%@#7&^/_!...brrr..." );
  495.             return False;
  496.     }
  497.     return True ;
  498. }
  499.  
  500.  
  501. /*
  502. **    Function name : MenuReadFile
  503. **
  504. **    Description : Commade 'read file' a partir du menu.
  505. **    Input : Le text courant.
  506. **    Ouput :
  507. */
  508. void MenuReadFile ( text )
  509.     Text *text;
  510. {
  511.     register     char *str = 0;
  512.        Text *result;
  513.     char c = '\007'; /* ^G */
  514.  
  515.        if ( GetVisibility ( dpy, text ) == False )
  516.         return;
  517.  
  518.     if ( GetModif ( text ) == True ) {
  519.               if ( SaveCurrentBuffer ( text, F_MENU ) != True )
  520.                   return;
  521.     }
  522.     ClearMessageWindow ( text -> mwin );
  523.     str = (char *) GetStringFromSelect ( text -> window, FILESELECT ); 
  524.     if ( (str == NULL) || (strncmp(str, &c, 1)) == NULL ) {
  525.         DisplayMessage ( text -> mwin, "Abort" );
  526.               if ( str != 0 )
  527.             (void) free ( str );
  528.         return;
  529.     }
  530.     TextCursorOff ( text );
  531.     if ( LoadFile ( text, str, NEW ) != -1 ) {
  532.         ShowScrollFrame ( dpy, text -> swin );
  533.         FirstPage ( text );
  534.         SetTextSave ( text );
  535.         if ( IsAlreadyLoad ( text -> filename, &result ) > 1 ) {
  536.             XBell ( dpy, 10 );
  537.             DisplayMessage ( text -> mwin, "Warning ...Already loaded" );
  538.         }
  539.     }
  540.     TextCursorOn ( text );
  541.        if ( str != 0 )
  542.         (void) free ( str );
  543. }
  544.  
  545.  
  546. /*
  547. **    Function name : MenuInsertFile
  548. **
  549. **    Description : Commande 'insert file' a partir du menu.
  550. **    Input : Le text courant.
  551. **    Ouput :
  552. */
  553. void MenuInsertFile ( text )
  554.     Text *text;
  555. {
  556.     register char *str;
  557.     char c = '\007'; /* ^G */
  558.  
  559.      if ( GetVisibility ( dpy, text ) == False )
  560.         return;
  561.  
  562.     ClearMessageWindow ( text -> mwin );
  563.     str = (char *) GetStringFromSelect ( text -> window, FILESELECT );
  564.     if ( (str == NULL) || (strncmp(str, &c, 1)) == NULL ) {
  565.         DisplayMessage ( text -> mwin, "Abort" );
  566.               if ( str != 0 )
  567.             (void) free ( str );
  568.         return;
  569.     }
  570.     TextCursorOff ( text );
  571.     if ( LoadFile ( text, str,  INSERT ) != -1 ) {
  572.         SetTextModif ( text );
  573.         SetAndDisplayPage ( text );
  574.         ShowScrollFrame ( dpy, text -> swin );
  575.         (void) MoveScrollBar ( dpy, text -> swin, 
  576.             CURRENT, text -> no_current_line - text -> n1 - 1 );
  577.     }
  578.     TextCursorOn ( text );
  579.        if ( str != 0 )
  580.         (void) free ( str );
  581. }
  582.  
  583.  
  584. /*
  585. **    Function name : MenuSaveFile
  586. **
  587. **    Description : Commande 'save file' a partir du menu.
  588. **    Input : Le text courant.
  589. **    Ouput :
  590. */
  591. void MenuSaveFile ( text )
  592.     Text *text;
  593. {
  594.     register char   *name;
  595.     char c = '\007';
  596.  
  597.      if ( GetVisibility ( dpy, text ) == False )
  598.         return;
  599.  
  600.     if ( strcmp (text -> filename, "NoName") == NULL ) {
  601.         name = (char *) GetStringFromDialogBox ( text -> window, "Write file : " );
  602.         if ( (name == NULL) || strncmp(name, &c,1) == NULL ) {
  603.             DisplayMessage ( text -> mwin, "Abort" );
  604.             return;
  605.         }
  606.         else {
  607.             if ( *name == '/' ) {
  608.                 (void) strcpy ( text -> filename, name );
  609.             }
  610.             else {
  611.                 (void) strcpy ( text -> filename,  text -> current_dir );
  612.                 (void) strcat ( text -> filename, "/" );
  613.                 (void) strcat ( text -> filename, name );
  614.             }
  615.             WriteFile ( text );
  616.         }
  617.     }
  618.     else {
  619. #ifdef DEBUG
  620.         (void) sprintf ( buf, "cp %s '#%s'\n",
  621.             text -> filename, text -> filename );
  622.         system ( buf );
  623. #endif DEBUG
  624.         if ( text -> modif == True )
  625.             WriteFile ( text );
  626.         else
  627.             DisplayMessage ( text -> mwin, "No changes" );
  628.     }
  629. }
  630.  
  631.  
  632. /*
  633. **    Function name : MenuWriteFile
  634. **
  635. **    Description : Commande 'write file' a partir du menu.
  636. **    Input : Le text courant.
  637. **    Ouput :
  638. */
  639. void MenuWriteFile ( text )
  640.     Text *text;
  641. {
  642.     register char *s;
  643.     char buf [128];
  644.     char c = '\007';
  645.     register char *name;
  646.  
  647.      if ( GetVisibility ( dpy, text ) == False )
  648.         return;
  649.  
  650. #ifdef DEBUG
  651.     (void) fprintf ( stderr, "Write File from menu\n" );
  652. #endif DEBUG
  653.     if ( (name = (char * ) strrchr ( text -> filename, '/' )) != 0 )
  654.         (void) sprintf ( buf, "Write file [%s]  : ", ++name );
  655.     else
  656.         (void) sprintf ( buf, "Write file [%s]  : ", text -> filename );    
  657.  
  658.     s = GetStringFromDialogBox ( text -> window, buf );
  659.     if ( (s == 0) || (strncmp(s,"y",1) == 0) ) {
  660.         WriteFile ( text );
  661.     }
  662.     else if ( (strncmp(s,"n",1 ) == 0) || (strncmp(s,&c,1)== 0) ) {
  663.         DisplayMessage ( text -> mwin, "Abort" );
  664.     }
  665.     else {
  666.         if ( *s == '/' ) {
  667.             (void) strcpy ( text -> filename, s );
  668.         }
  669.         else {
  670.             (void) strcpy ( text -> filename,  text -> current_dir );
  671.             (void) strcat ( text -> filename, "/" );
  672.             (void) strcat ( text -> filename, s );
  673.         }
  674.         WriteFile ( text );
  675.               XStoreName ( dpy, text ->  w_parent, text -> filename );   
  676.     }
  677. }
  678.  
  679.  
  680. /*
  681. **    Function name : SaveCurrentBuffer
  682. **
  683. **    Description : Sauve le buffer courant.
  684. **    Input : Le text courant, clavier/menu.
  685. **    Ouput :
  686. */
  687. int SaveCurrentBuffer ( text, from )
  688.     Text *text;
  689.     register int from;
  690. {
  691.     register     char *str = 0;
  692.     char c = '\007'; /* ^G */
  693.        register char *buf, *name;
  694.     
  695.        buf = (char *) malloc ( (unsigned) strlen ( text -> filename ) + 64 );
  696.  
  697.     if ( (name = (char * ) strrchr ( text -> filename, '/' )) != 0 )
  698.         (void) sprintf ( buf, "Save buffer [%s] ? [y/n]", ++name );
  699.     else
  700.     (void) sprintf ( buf ,"Save buffer [%s] ? [y/n] ", text -> filename );
  701.  
  702.     if ( from == F_KEY )   
  703.         str = (char * ) GetString ( text, buf, (char *) 0);
  704.     else 
  705.         str = (char * ) GetStringFromDialogBox ( text -> window, buf );
  706.     while ( True ) {
  707.         if ( (str == NULL) || (strncmp(str,"y",1) == NULL) ) {
  708.             WriteFile ( text );
  709.             break;
  710.         }
  711.         if ( strncmp(str,&c,1) == NULL ) {
  712.             DisplayMessage ( text -> mwin, "Abort" );
  713.                      if ( buf != 0 )
  714.                 (void) free ( buf );
  715.             return False;
  716.         }
  717.         if ( strncmp(str,"n",1) == NULL ) {
  718.             break;
  719.         }
  720.         if ( from == F_KEY )
  721.             str = (char *) GetString ( text,
  722.                 "Please answer y or n : ", (char *) 0 );
  723.         else
  724.             str = (char * ) GetStringFromDialogBox ( text -> window,
  725.                 "Please answer y or n : "  );    
  726.     }
  727.        if ( buf != 0 )
  728.            (void) free ( buf );
  729.     return True;
  730. }
  731.  
  732.  
  733. /*
  734. **    Function name : MenuGotoLine
  735. **
  736. **    Description : Va a la ligne n.
  737. **    Input : Le text courant.
  738. **    Ouput :
  739. */
  740. void MenuGotoLine ( text )
  741.     Text *text;
  742. {
  743.     register int n;
  744.     register char *str;
  745.     char c = '\007';
  746.  
  747.      if ( GetVisibility ( dpy, text ) == False )
  748.         return;
  749.  
  750.     str = (char * ) GetStringFromDialogBox ( text -> window, "Line Number : " );
  751.     if ( (str == 0) || (strncmp (str, &c, 1 ) == 0) || ((n = atoi ( str )) == 0) )
  752.         DisplayMessage ( text -> mwin, "Abort" );
  753.     else {
  754.         TextCursorOff ( text );
  755.         GotoLineNumber ( text, n );
  756.         CurrentLineToMiddle ( text ); 
  757.         TextCursorOn ( text );
  758.     }
  759. }
  760.  
  761.  
  762. /*
  763. **    Function name : KillCurrentBuffer
  764. **
  765. **    Description : Comme son nom l'indique.
  766. **    Input : Le text courant.
  767. **    Ouput :
  768. */
  769. void KillCurrentBuffer ( text )
  770.     Text *text;
  771. {
  772.     if ( GetModif ( text ) == True ) {
  773.               if ( SaveCurrentBuffer ( text, F_KEY ) != True )
  774.                   return;
  775.     }
  776.     KillText ( dpy, text );
  777.     RefreshScroll ( dpy,  text -> swin, 
  778.         text -> width + GetScrollWidth () + W_SPACE + 1, text -> height, 0 );
  779.     SetTextSave ( text );
  780.        SetDirAndFilename ( text, "NoName" );
  781.     XStoreName ( dpy, text ->  w_parent, "NoName" );   
  782. }
  783.