[uae] Symbolic link support in the filesystem.

  • From: Jeff Shepherd <BeaveMan27@xxxxxxxx>
  • To: UAE Mailing List <uae@xxxxxxxxxxxxx>
  • Date: Fri, 09 Apr 2004 12:55:19 -0400

I originally did this hack way back in 0.8.19 days. I thought it is a something very useful (and I don't want to keep applying the patch) so I am posting it to the list.

The patch allows for symbolic links in the filesystem. Things like ln and ln -s work now on the Amiga. What this patch doesn't do is show the link with "ls -l".

--
Jeff Shepherd
BeaveMan27@xxxxxxxx

*** uae-0.8.25-20040302.orig/src/filesys.c      2004-03-01 22:10:32.000000000 
-0500
--- uae-0.8.25-20040302/src/filesys.c   2004-04-09 12:47:36.777857382 -0400
***************
*** 591,594 ****
--- 591,597 ----
  #define DISK_TYPE             0x444f5301 /* DOS\1 */
  
+ #define LINK_HARD     0
+ #define LINK_SOFT     1
+ 
  typedef struct {
      uae_u32 uniq;
***************
*** 714,717 ****
--- 717,732 ----
  }
  
+ 
+ static char *cstr (Unit *unit, uaecptr addr)
+ {
+     int i;
+     int n = get_byte(addr);
+ 
+     for (i = 0; i < n; i++, addr++)
+       unit->tmpbuf3[i] = get_byte(addr);
+     unit->tmpbuf3[i] = 0;
+     return unit->tmpbuf3;
+ }
+ 
  static char *bstr_cut (Unit *unit, uaecptr addr)
  {
***************
*** 1860,1863 ****
--- 1875,1902 ----
  }
  
+ static void
+ action_copy_dir_fh (Unit *unit, dpacket packet)
+ {
+   Key *k = lookup_key (unit, GET_PCK_ARG1 (packet));
+   a_inode *aino = (a_inode *)0;
+ 
+   if (k != 0)
+     aino = k->aino;
+   if (aino == 0)
+     aino = &unit->rootnode;
+ 
+     /* DupLock()ing exclusive locks isn't possible, says the Autodoc, but
+      * at least the RAM-Handler seems to allow it. Let's see what happens
+      * if we don't. */
+     if (aino->elock) {
+       PUT_PCK_RES1 (packet, DOS_FALSE);
+       PUT_PCK_RES2 (packet, ERROR_OBJECT_IN_USE);
+       return;
+     }
+     aino->shlock++;
+     PUT_PCK_RES1 (packet, make_lock (unit, aino->uniq, -2) >> 2);
+ }
+ 
+ 
  /* convert time_t to/from AmigaDOS time */
  const int secs_per_day = 24 * 60 * 60;
***************
*** 3191,3194 ****
--- 3230,3289 ----
  }
  
+ static void
+ action_make_link (Unit *unit, dpacket packet)
+ {
+   uaecptr lock = GET_PCK_ARG1 (packet) << 2;
+   uaecptr to = GET_PCK_ARG2 (packet) << 2;
+   uaecptr from = GET_PCK_ARG3 (packet);
+   long mode = GET_PCK_ARG4 (packet);
+   char *slash;
+   uae_u32 err;
+ 
+   a_inode *afrom, *ato, *aparent;
+ 
+   TRACE(("ACTION_MAKE_LINK(\"%s\", \"%s\")\n", cstr (unit, from), bstr(unit, 
to)));
+ 
+   afrom = find_aino (unit, lock, cstr(unit, from), &err);
+   if (err != 0 || afrom == 0) {
+     PUT_PCK_RES1 (packet, DOS_FALSE);
+     PUT_PCK_RES2 (packet, err);
+     return;
+   }
+ 
+   ato = find_aino (unit, lock, bstr(unit, to), &err);
+   
+   /* file already exists */
+   if (err != ERROR_OBJECT_NOT_AROUND || ato == 0) {
+     PUT_PCK_RES1 (packet, DOS_FALSE);
+     PUT_PCK_RES2 (packet, ERROR_OBJECT_EXISTS);
+     return;
+   }
+ 
+ 
+   ato = create_child_aino(unit, ato, bstr_cut(unit, to), afrom->dir);
+   switch (mode) {
+   case LINK_SOFT:
+     if (symlink(afrom->nname, ato->nname) != 0) {
+       PUT_PCK_RES1(packet, DOS_FALSE);
+       PUT_PCK_RES2(packet, dos_errno());
+       return;
+     }
+     break;
+ 
+   case LINK_HARD:
+     if (link(afrom->nname, ato->nname) != 0) {
+       PUT_PCK_RES1(packet, DOS_FALSE);
+       PUT_PCK_RES2(packet, dos_errno());
+       return;
+     }
+     break;
+   }
+ 
+   de_recycle_aino(unit, ato);
+   de_recycle_aino(unit, afrom);
+ 
+   PUT_PCK_RES1(packet, DOS_TRUE);
+ }
+ 
  /* We don't want multiple interrupts to be active at the same time. I don't
   * know whether AmigaOS takes care of that, but this does. */
***************
*** 3364,3374 ****
       case ACTION_ADD_NOTIFY: action_add_notify (unit, pck); break;
       case ACTION_REMOVE_NOTIFY: action_remove_notify (unit, pck); break;
  
       /* unsupported packets */
       case ACTION_LOCK_RECORD:
       case ACTION_FREE_RECORD:
-      case ACTION_COPY_DIR_FH:
       case ACTION_EXAMINE_ALL:
!      case ACTION_MAKE_LINK:
       case ACTION_READ_LINK:
       case ACTION_FORMAT:
--- 3459,3470 ----
       case ACTION_ADD_NOTIFY: action_add_notify (unit, pck); break;
       case ACTION_REMOVE_NOTIFY: action_remove_notify (unit, pck); break;
+      case ACTION_MAKE_LINK: action_make_link(unit, pck); break;
+      case ACTION_COPY_DIR_FH: action_copy_dir_fh(unit, pck); break;
  
       /* unsupported packets */
       case ACTION_LOCK_RECORD:
       case ACTION_FREE_RECORD:
       case ACTION_EXAMINE_ALL:
! 
       case ACTION_READ_LINK:
       case ACTION_FORMAT:

Other related posts: