Re: [AD] Some points about the grabber

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> > For my projects, I store both my datafiles and source code on a
> > Windows partitition and access it in Linux through symlinks - this
> > way, I can get to the same files easily.
> > The problem is that the grabber destroys these symlinks for datafiles.
> > opening the datafile in the grabber works as expected, saving it
> > overwrites the symlink with a real file sprites.dat, which is very
> > annoying. I don't know enough about Linux programming to fix this
> > personally.
>
> (*pssst* man realpath)
>
> I'm not sure if your intended behaviour is absolutely the Right Thing
> to do though.

Ok, this turned out to be less tricky and time consuming than I had 
thought. I made a modification that checks if the target file, if it 
exists, is a symlink. If it is, it asks wether to overwrite the link or 
the file it points to.
Patch attached.
Tested under Linux, DJGPP and MingW (where the test of the latter two 
consists more of seeing wether it compiles than if it actually works), but 
the code introduces some platform dependent code, so tests under other 
UNIX-like systems may be needed.
Note that I didn't apply the patch Peter submitted earlier concerning the 
commandline options before generating the diff. Not sure if that matters, 
though.

On a side note, is the 80 characters mentioned in the line

/* 80 characters * maximum character width (6 bytes for UTF8) */
#define FILENAME_LENGTH (80*6)

really a safe margin? It seems extremely small to me...
*** alleg401/tools/grabber.c	Thu Apr  4 18:29:42 2002
--- allegro/tools/grabber.c	Thu Apr  4 19:19:05 2002
***************
*** 28,33 ****
--- 28,39 ----
     #include <sys/exceptn.h>
  #endif
  
+ #if (defined ALLEGRO_UNIX) && (!defined SCAN_DEPEND)
+    #include <unistd.h>
+    #include <sys/stat.h>   
+ #endif
+ 
+ 
  
  /* 80 characters * maximum character width (6 bytes for UTF8) */
  #define FILENAME_LENGTH (80*6)
***************
*** 1754,1763 ****
--- 1760,1799 ----
  
  
  
+ /* check if the filename is a real file, or a symlink */
+ static int file_is_symlink(const char *filename)
+ {
+ #if (defined ALLEGRO_DOS) || (defined ALLEGRO_WINDOWS)
+    return FALSE;
+ #else
+    struct stat buf;
+    
+    lstat (filename, &buf);
+    
+    return (buf.st_mode & S_IFLNK == S_IFLNK);
+ #endif
+ }
+ 
+ 
+ 
+ /* Resolve a symbolic link. Returns a copy of the unmodified path on DOS/Windows */
+ static char *resolve_symbolic_link(const char *path, char *resolved_path)
+ {
+ #if (defined ALLEGRO_DOS) || (defined ALLEGRO_WINDOWS)
+    sprintf (resolved_path, "%s", path);
+    return resolved_path;
+ #else
+    return realpath(path, resolved_path);
+ #endif
+ }
+ 
+ 
+ 
  /* do the actual work of saving a file */
  static int save(int strip)
  {
     char buf[FILENAME_LENGTH], buf2[256];
+    char real_filename[FILENAME_LENGTH];
     int err = FALSE;
  
     strcpy(buf, data_file);
***************
*** 1768,1781 ****
  	 if (alert(buf2, NULL, NULL, "Yes", "Cancel", 'y', 27) != 1)
  	    return D_REDRAW;
        }
  
        box_start();
  
        set_mouse_sprite(my_busy_pointer);
        busy_mouse = TRUE;
  
!       fix_filename_case(buf);
!       strcpy(data_file, buf);
        main_dlg[DLG_FILENAME].d2 = strlen(data_file);
  
        update_info();
--- 1804,1833 ----
  	 if (alert(buf2, NULL, NULL, "Yes", "Cancel", 'y', 27) != 1)
  	    return D_REDRAW;
        }
+       
+       if (exists(buf) && file_is_symlink(buf)) {
+          sprintf(buf2, "%s is a symbolic link.", buf);
+          if (alert(buf2, "Do you want to overwrite the link, or the file it points to?", NULL, "Link", "File", 'l', 'f')==1) {
+             sprintf (real_filename, "%s", buf);
+          }
+          else {
+             if (resolve_symbolic_link(buf, real_filename) != real_filename) {
+                alert ("Error resolving link!", NULL, NULL, "Oops", NULL, 27, 0);
+                return D_REDRAW;
+             }
+          }
+       }
+       else {
+          sprintf (real_filename, "%s", buf);
+       }
  
        box_start();
  
        set_mouse_sprite(my_busy_pointer);
        busy_mouse = TRUE;
  
!       fix_filename_case(real_filename);
!       strcpy(data_file, real_filename);
        main_dlg[DLG_FILENAME].d2 = strlen(data_file);
  
        update_info();


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/