home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 191.lha / ARequester / reqdir.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  5KB  |  216 lines

  1. #include <libraries/dosextens.h>
  2. #include "reqdir.h"
  3.  
  4. #define ALIGN(X) ((X+1)&~1)
  5. #define DaysInYear(year) ((year%4) ? 365 : 366)
  6.  
  7. /* Array of entry pointers */
  8. static Entry **ent;
  9. static ULONG num_entries, max_entries;
  10. static char *buffer_max;
  11.  
  12. extern struct Lock *Lock();
  13. extern short Examine();
  14. extern short ExNext();
  15. extern long IoErr();
  16. extern char *strcpy();
  17. extern void UnLock();
  18. extern void *AllocMem();
  19.  
  20.  
  21. static void put_date(e,fib)
  22. register Entry *e;
  23. struct FileInfoBlock *fib;
  24. {
  25. register UWORD year, month;
  26. register long d;
  27. static UWORD days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
  28.  
  29. /* figure out what year */
  30. for( year = 1978, d = fib->fib_Date.ds_Days; d > DaysInYear(year);)
  31.    { d -= DaysInYear(year); year++; }
  32.  
  33. /* there are 29 days in February in a leap year */
  34. days[1] = (year % 4) ? 28 : 29;
  35.  
  36. /* figure out what month */
  37. for( month = 0; d > days[month]; month++)
  38.    d -= days[month];
  39.  
  40. e->month = month+1;
  41. e->day = d+1;
  42. e->year = year - 1978;
  43. }
  44.  
  45.  
  46. /* adds a directory entry to the buffer */
  47.  
  48. static char *add_entry(curr,fib)
  49. register char *curr;
  50. register struct FileInfoBlock *fib;
  51. {
  52. register Entry *e;
  53. register char *next;
  54. register UWORD len;
  55.  
  56. len = ALIGN(strlen(fib->fib_FileName) + 1);
  57.  
  58. /* check for space in the buffer */
  59. if( (next = curr + (sizeof(Entry) + len*sizeof(char)) )  > buffer_max )
  60.    return(0L);
  61.  
  62. e = (Entry *)curr;
  63. e->size = len + sizeof(Entry);
  64.  
  65. strcpy(EntryName(e),fib->fib_FileName);
  66.  
  67. if( !(e->dir = ((fib->fib_EntryType > 0) ? 1 : 0)) )
  68.    {
  69.    e->archive = (fib->fib_Protection & FIBF_ARCHIVE) ? 0 : 1;
  70.    e->read    = (fib->fib_Protection & FIBF_READ)    ? 0 : 1;
  71.    e->write   = (fib->fib_Protection & FIBF_WRITE)   ? 0 : 1;
  72.    e->execute = (fib->fib_Protection & FIBF_EXECUTE) ? 0 : 1;
  73.    e->delete  = (fib->fib_Protection & FIBF_DELETE)  ? 0 : 1;
  74.    }
  75.  
  76. put_date(e,fib);
  77.  
  78. if( num_entries < max_entries )
  79.    ent[num_entries] = e;
  80. else return(0L);
  81.  
  82. return(next);
  83. }
  84.  
  85.  
  86. static short comp(i,j)
  87. register ULONG i, j;
  88. {
  89. extern short strcmpa();
  90.  
  91. if( ent[i]->dir != ent[j]->dir )
  92.    return( (short)(ent[j]->dir - ent[i]->dir) );
  93. return( strcmpa(EntryName(ent[i]),EntryName(ent[j])) );
  94. }
  95.  
  96. static void swap(i,j)
  97. register ULONG i, j;
  98. {
  99. register Entry *e;
  100. e = ent[i];
  101. ent[i] = ent[j];
  102. ent[j] = e;
  103. }
  104.  
  105. /* Returns the number of directory entries found or an error */
  106.  
  107. long reqdir(name,buffer,bufsize,entries,maxent)
  108. char *name;        /* => The directory to lock first */
  109. char *buffer;      /* => The buffer for the directory entries */
  110. ULONG bufsize;      /* => The size of the buffer for dir entries */
  111. Entry *entries[];  /* <= A sorted array of directory entry pointers */
  112. ULONG maxent;       /* => The maximum number of directory entries */
  113. {
  114. register struct Lock *lock;
  115. register char *max = buffer + (bufsize - 1);
  116. register char *curr = buffer;
  117. register struct FileInfoBlock *fib;
  118. short error;
  119.  
  120. /* Assign some global variables so the sorting functions
  121.  * can get at them */
  122. ent = entries;
  123. max_entries = maxent;
  124. buffer_max = max;
  125.  
  126. if( !(lock = Lock(name,(long)ACCESS_READ)) )
  127.    return(-1L);
  128.  
  129. if( !(fib = AllocMem((long)sizeof(struct FileInfoBlock),(long)MEMF_CLEAR)) )
  130.    {
  131.    UnLock(lock);
  132.    return(-1L);
  133.    }
  134. if( !Examine(lock, fib) )
  135.    {
  136.    UnLock(lock);
  137.    return(-1L);
  138.    }
  139. if( fib->fib_DirEntryType <= 0 )
  140.    {
  141.    FreeMem(fib,(long)sizeof(struct FileInfoBlock));
  142.    UnLock(lock);
  143.    return(-2L);
  144.    }
  145.  
  146. /* always add the parent directory to the list of entries */
  147. num_entries = 0L;
  148. fib->fib_EntryType = 1;
  149. strcpy(fib->fib_FileName,"/");
  150. curr = add_entry(curr,fib);
  151.  
  152.  
  153. for(num_entries = 1L;;)
  154.    {
  155.    if( !ExNext(lock,fib) )
  156.       if( IoErr() == ERROR_NO_MORE_ENTRIES )
  157.          break;
  158.    if( !(curr = add_entry(curr,fib)) )
  159.       break;
  160.    num_entries++;
  161.    }
  162.  
  163. UnLock(lock);
  164.  
  165. /* Sort the directory entries */
  166. if( num_entries )
  167.    quicksort(num_entries,comp,swap);
  168.  
  169. FreeMem(fib,(long)sizeof(struct FileInfoBlock));
  170.  
  171. return((long)num_entries);
  172. }
  173.  
  174.  
  175. /* This is need to convert the stupid BCPL strings */
  176. UBYTE *bstrcpy(dest,src)
  177. register UBYTE *dest;
  178. BSTR *src;
  179. {
  180. register char *string;
  181. register UWORD length, i;
  182.  
  183. string = (char *) BADDR(src);
  184. length = *string++;
  185.  
  186. for( i = 0; i < length; i++)
  187.    dest[i] = string[i];
  188.  
  189. dest[length] = '\0';
  190.  
  191. return(dest);
  192. }
  193.  
  194.  
  195. void init_dir(path,ac)
  196. UBYTE *path;
  197. short ac;
  198. {
  199. extern struct Task *FindTask();
  200.  
  201. register struct Process *me;
  202.  
  203. me = (struct Process *)FindTask(0L);
  204.  
  205. /* find the current directrory */
  206. if( ac )  /* startup from the CLI */
  207.    {
  208.    register struct CommandLineInterface *cli =
  209.       (struct CommandLineInterface *) BADDR(me->pr_CLI);
  210.    bstrcpy(path,cli->cli_SetName);
  211.    }
  212. else path[0] = '\0';
  213.  
  214. }
  215.  
  216.