Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Haiku platform-dependent support routines for PhysicsFS.
  3.  *
  4.  * Please see the file LICENSE.txt in the source's root directory.
  5.  *
  6.  *  This file written by Ryan C. Gordon.
  7.  */
  8.  
  9. #define __PHYSICSFS_INTERNAL__
  10. #include "physfs_platforms.h"
  11.  
  12. #ifdef PHYSFS_PLATFORM_HAIKU
  13.  
  14. #include <os/kernel/OS.h>
  15. #include <os/app/Roster.h>
  16. #include <os/storage/Volume.h>
  17. #include <os/storage/VolumeRoster.h>
  18. #include <os/storage/Directory.h>
  19. #include <os/storage/Entry.h>
  20. #include <os/storage/Path.h>
  21. #include <os/kernel/fs_info.h>
  22. #include <os/device/scsi.h>
  23.  
  24. #include <errno.h>
  25. #include <unistd.h>
  26.  
  27. #include "physfs_internal.h"
  28.  
  29. int __PHYSFS_platformInit(void)
  30. {
  31.     return 1;  /* always succeed. */
  32. } /* __PHYSFS_platformInit */
  33.  
  34.  
  35. void __PHYSFS_platformDeinit(void)
  36. {
  37.     /* no-op */
  38. } /* __PHYSFS_platformDeinit */
  39.  
  40.  
  41. static char *getMountPoint(const char *devname, char *buf, size_t bufsize)
  42. {
  43.     BVolumeRoster mounts;
  44.     BVolume vol;
  45.  
  46.     mounts.Rewind();
  47.     while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
  48.     {
  49.         fs_info fsinfo;
  50.         fs_stat_dev(vol.Device(), &fsinfo);
  51.         if (strcmp(devname, fsinfo.device_name) == 0)
  52.         {
  53.             BDirectory directory;
  54.             BEntry entry;
  55.             BPath path;
  56.             const char *str;
  57.  
  58.             if ( (vol.GetRootDirectory(&directory) < B_OK) ||
  59.                  (directory.GetEntry(&entry) < B_OK) ||
  60.                  (entry.GetPath(&path) < B_OK) ||
  61.                  ( (str = path.Path()) == NULL) )
  62.                 return NULL;
  63.  
  64.             strncpy(buf, str, bufsize-1);
  65.             buf[bufsize-1] = '\0';
  66.             return buf;
  67.         } /* if */
  68.     } /* while */
  69.  
  70.     return NULL;
  71. } /* getMountPoint */
  72.  
  73.  
  74.     /*
  75.      * This function is lifted from Simple Directmedia Layer (SDL):
  76.      *  https://www.libsdl.org/  ... this is zlib-licensed code, too.
  77.      */
  78. static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
  79. {
  80.     BDirectory dir;
  81.     dir.SetTo(d);
  82.     if (dir.InitCheck() != B_NO_ERROR)
  83.         return;
  84.  
  85.     dir.Rewind();
  86.     BEntry entry;
  87.     while (dir.GetNextEntry(&entry) >= 0)
  88.     {
  89.         BPath path;
  90.         const char *name;
  91.         entry_ref e;
  92.  
  93.         if (entry.GetPath(&path) != B_NO_ERROR)
  94.             continue;
  95.  
  96.         name = path.Path();
  97.  
  98.         if (entry.GetRef(&e) != B_NO_ERROR)
  99.             continue;
  100.  
  101.         if (entry.IsDirectory())
  102.         {
  103.             if (strcmp(e.name, "floppy") != 0)
  104.                 tryDir(name, callback, data);
  105.             continue;
  106.         } /* if */
  107.  
  108.         const int devfd = open(name, O_RDONLY);
  109.         if (devfd < 0)
  110.             continue;
  111.  
  112.         device_geometry g;
  113.         const int rc = ioctl(devfd, B_GET_GEOMETRY, &g, sizeof (g));
  114.         close(devfd);
  115.         if (rc < 0)
  116.             continue;
  117.  
  118.         if (g.device_type != B_CD)
  119.             continue;
  120.  
  121.         char mntpnt[B_FILE_NAME_LENGTH];
  122.         if (getMountPoint(name, mntpnt, sizeof (mntpnt)))
  123.             callback(data, mntpnt);
  124.     } /* while */
  125. } /* tryDir */
  126.  
  127.  
  128. void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
  129. {
  130.     tryDir("/dev/disk", cb, data);
  131. } /* __PHYSFS_platformDetectAvailableCDs */
  132.  
  133.  
  134. static team_id getTeamID(void)
  135. {
  136.     thread_info info;
  137.     thread_id tid = find_thread(NULL);
  138.     get_thread_info(tid, &info);
  139.     return info.team;
  140. } /* getTeamID */
  141.  
  142.  
  143. char *__PHYSFS_platformCalcBaseDir(const char *argv0)
  144. {
  145.     image_info info;
  146.     int32 cookie = 0;
  147.  
  148.     while (get_next_image_info(0, &cookie, &info) == B_OK)
  149.     {
  150.         if (info.type == B_APP_IMAGE)
  151.             break;
  152.     } /* while */
  153.  
  154.     BEntry entry(info.name, true);
  155.     BPath path;
  156.     status_t rc = entry.GetPath(&path);  /* (path) now has binary's path. */
  157.     assert(rc == B_OK);
  158.     rc = path.GetParent(&path); /* chop filename, keep directory. */
  159.     assert(rc == B_OK);
  160.     const char *str = path.Path();
  161.     assert(str != NULL);
  162.     const size_t len = strlen(str);
  163.     char *retval = (char *) allocator.Malloc(len + 2);
  164.     BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
  165.     strcpy(retval, str);
  166.     retval[len] = '/';
  167.     retval[len+1] = '\0';
  168.     return retval;
  169. } /* __PHYSFS_platformCalcBaseDir */
  170.  
  171.  
  172. char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
  173. {
  174.     const char *userdir = __PHYSFS_getUserDir();
  175.     const char *append = "config/settings/";
  176.     const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
  177.     char *retval = (char *) allocator.Malloc(len);
  178.     BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
  179.     snprintf(retval, len, "%s%s%s/", userdir, append, app);
  180.     return retval;
  181. } /* __PHYSFS_platformCalcPrefDir */
  182.  
  183. #endif  /* PHYSFS_PLATFORM_HAIKU */
  184.  
  185. /* end of physfs_platform_haiku.cpp ... */
  186.  
  187.