home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / mtools_3.6.src.lzh / MTOOLS_3.6 / directory.c < prev    next >
C/C++ Source or Header  |  1997-11-12  |  4KB  |  165 lines

  1. #include "sysincludes.h"
  2. #include "msdos.h"
  3. #include "stream.h"
  4. #include "mtools.h"
  5. #include "file.h"
  6. #include "vfat.h"
  7. #include "fs.h"
  8.  
  9. /* #define DEBUG */
  10.  
  11. /*
  12.  * Read a directory entry into caller supplied buffer
  13.  */
  14. struct directory *dir_read(Stream_t *Dir,
  15.                struct directory *dir, 
  16.                int num,
  17.                struct vfat_state *v)
  18. {
  19.     if(force_read(Dir, (char *) dir, num * MDIR_SIZE, MDIR_SIZE) !=
  20.        MDIR_SIZE)
  21.         return NULL;
  22.  
  23.     if (v && (dir->attr == 0x0f) && dir->name[0] != DELMARK) {
  24.         struct vfat_subentry *vse;
  25.         unsigned char id, last_flag;
  26.         char *c;
  27.  
  28.         vse = (struct vfat_subentry *) dir;
  29.  
  30.         id = vse->id & VSE_MASK;
  31.         last_flag = (vse->id & VSE_LAST);
  32.         if (id > MAX_VFAT_SUBENTRIES) {
  33.             fprintf(stderr, "dir_read: invalid VSE ID %d at %d.\n",
  34.                 id, num);
  35.             return dir;
  36.         }
  37.  
  38. /* 950819: This code enforced finding the VSEs in order.  Well, Win95
  39.  * likes to write them in *reverse* order for some bizarre reason!  So
  40.  * we pretty much have to tolerate them coming in any possible order.
  41.  * So skip this check, we'll do without it (What does this do, Alain?).
  42.  *
  43.  * 950820: Totally rearranged code to tolerate any order but to warn if
  44.  * they are not in reverse order like Win95 uses.
  45.  *
  46.  * 950909: Tolerate any order. We recognize new chains by mismatching
  47.  * checksums. In the event that the checksums match, new entries silently
  48.  * overwrite old entries of the same id. This should accept all valid
  49.  * entries, but may fail to reject invalid entries in some rare cases.
  50.  */
  51.  
  52.         /* bad checksum, begin new chain */
  53.         if(v->sum != vse->sum) {
  54.             clear_vfat(v);
  55.             v->sum = vse->sum;
  56.         }
  57.  
  58. #ifdef DEBUG
  59.         if(v->status & (1 << (id-1)))
  60.             fprintf(stderr,
  61.                 "dir_read: duplicate VSE %d\n", vse->id);
  62. #endif
  63.             
  64.         v->status |= 1 << (id-1);
  65.         if(last_flag)
  66.             v->subentries = id;
  67.             
  68. #ifdef DEBUG
  69.         if (id > v->subentries)
  70.             /* simple test to detect entries preceding
  71.              * the "last" entry (really the first) */
  72.             fprintf(stderr,
  73.                 "dir_read: new VSE %d sans LAST flag\n",
  74.                 vse->id);
  75. #endif
  76.  
  77.         c = &(v->name[VSE_NAMELEN * (id-1)]);
  78.         c += unicode_read(vse->text1, c, VSE1SIZE);
  79.         c += unicode_read(vse->text2, c, VSE2SIZE);
  80.         c += unicode_read(vse->text3, c, VSE3SIZE);
  81. #ifdef DEBUG
  82.         printf("Read VSE %d at %d, subentries=%d, = (%13s).\n",
  83.                id,num,v->subentries,&(v->name[VSE_NAMELEN * (id-1)]));
  84. #endif        
  85.         if (last_flag)
  86.             *c = '\0';    /* Null terminate long name */
  87.     }
  88.     return dir;
  89. }
  90.  
  91. /*
  92.  * Make a subdirectory grow in length.  Only subdirectories (not root)
  93.  * may grow.  Returns a 0 on success, 1 on failure (disk full), or -1
  94.  * on error.
  95.  */
  96.  
  97. int dir_grow(Stream_t *Dir, int size)
  98. {
  99.     Stream_t *Stream = GetFs(Dir);
  100.     DeclareThis(FsPublic_t);
  101.     int ret;
  102.     int buflen;
  103.     char *buffer;
  104.     
  105.     
  106.     buflen = This->cluster_size * This->sector_size;
  107.  
  108.     if(! (buffer=malloc(buflen)) ){
  109.         perror("dir_grow: malloc");
  110.         return -1;
  111.     }
  112.         
  113.     memset((char *) buffer, '\0', buflen);
  114.     ret = force_write(Dir, buffer, size * MDIR_SIZE, buflen);
  115.     if(ret < buflen)
  116.         return -1;
  117.     return 0;
  118. }
  119.  
  120.  
  121. void dir_write(Stream_t *Dir, int num, struct directory *dir)
  122. {
  123.     force_write(Dir, (char *) dir, num * MDIR_SIZE, MDIR_SIZE);
  124. }
  125.  
  126.  
  127. /*
  128.  * Make a directory entry.  Builds a directory entry based on the
  129.  * name, attribute, starting cluster number, and size.  Returns a pointer
  130.  * to a static directory structure.
  131.  */
  132.  
  133. struct directory *mk_entry(const char *filename, char attr,
  134.                unsigned int fat, size_t size, long date,
  135.                struct directory *ndir)
  136. {
  137.     struct tm *now;
  138.     time_t date2 = date;
  139.     unsigned char hour, min_hi, min_low, sec;
  140.     unsigned char year, month_hi, month_low, day;
  141.  
  142.     now = localtime(&date2);
  143.     strncpy(ndir->name, filename, 8);
  144.     strncpy(ndir->ext, filename + 8, 3);
  145.     ndir->attr = attr;
  146.     ndir->ctime_ms = 0;
  147.     hour = now->tm_hour << 3;
  148.     min_hi = now->tm_min >> 3;
  149.     min_low = now->tm_min << 5;
  150.     sec = now->tm_sec / 2;
  151.     ndir->ctime[1] = ndir->time[1] = hour + min_hi;
  152.     ndir->ctime[0] = ndir->time[0] = min_low + sec;
  153.     year = (now->tm_year - 80) << 1;
  154.     month_hi = (now->tm_mon + 1) >> 3;
  155.     month_low = (now->tm_mon + 1) << 5;
  156.     day = now->tm_mday;
  157.     ndir -> adate[1] = ndir->cdate[1] = ndir->date[1] = year + month_hi;
  158.     ndir -> adate[0] = ndir->cdate[0] = ndir->date[0] = month_low + day;
  159.  
  160.     set_word(ndir->start, fat & 0xffff);
  161.     set_word(ndir->startHi, fat >> 16);
  162.     set_dword(ndir->size, size);
  163.     return ndir;
  164. }
  165.