home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / alt_os / mint / mfs6011 / source / minixfs / dir.c < prev    next >
C/C++ Source or Header  |  1994-12-30  |  4KB  |  145 lines

  1. /* This file is part of 'minixfs' Copyright 1991,1992,1993 S.N.Henson */
  2.  
  3. #include "minixfs.h"
  4. #include "proto.h"
  5. #include "global.h"
  6.  
  7.  
  8. /* search_dir serves 3 functions dependent on 'mode'
  9. 0 Search a directory for the entry 'name' if found return its inode number.
  10. 1 Create an entry 'name' return position of d_inum .
  11. 2 Delete an entry 'name' return inode num for success .
  12. 3 Find entry 'name', return position of d_inum.
  13. In all cases failure is denoted by a negative error number .
  14. */
  15.  
  16. long search_dir(name,inum,drive,flag)
  17. const char *name;
  18. unsigned inum;
  19. int drive;
  20. int flag;
  21. {
  22.     int entry,count;
  23.     long zone;        /* Zone number within dir */
  24.     long lstfree;    /* Last unused dir entry */
  25.     d_inode rip;
  26.     cache *tmp;
  27.     int tflag;
  28.     int incr;
  29.     int mfname;
  30.     static char tname[MNAME_MAX];
  31.  
  32.     incr=super_ptr[drive]->increment;
  33.     mfname=MMAX_FNAME(incr);
  34.  
  35.     if( (tflag=do_trans(SRCH_TOS,drive)) )
  36.                 strcpy(tname,tosify(name,tflag,mfname));
  37.  
  38.     read_inode(inum,&rip,drive);
  39.     /* Must be a directory ! */
  40.     if(!IS_DIR(rip)) return EPTHNF;
  41.  
  42.     lstfree=-1l;
  43.     for(zone=0; (count=cnext_zone(&rip,zone,&tmp,drive)>>L_DIR_SIZE);
  44.     zone++)
  45.     {
  46.     dir_struct *try;
  47.         for(entry=0,try=tmp->buffer->bdir;entry<count;entry+=incr,try+=incr) {
  48.              unshort inumtemp;
  49.              inumtemp=try->d_inum;
  50.              if(inumtemp &&
  51.             (!strncmp(name,try->d_name,mfname) || (tflag && 
  52.         (!strcmp(tname,tosify(try->d_name,tflag,mfname)) ) )))
  53.  
  54.             {
  55.                 if(flag==KILL)
  56.             {
  57.                   /* Never ever allow unlinking of '.' or '..' */
  58.                   if(zone==0 && entry<(2 * incr))return EACCDN;
  59.                       try->d_inum=0;
  60.  
  61.             /* Next bit pinched from Minix,
  62.              * store old inode num in last 2 bytes of name
  63.              * This allows recovery in case of accident
  64.              */
  65.         *((unshort *)&try->d_name[MMAX_FNAME(incr)-2])=inumtemp;
  66.  
  67. #if 1
  68.             tmp->status=2;
  69. #else
  70.     /* buffer tmp points to _might_ be invalidated in find_zone... */
  71.                 write_zone(find_zone(&rip,zone,drive,0),tmp
  72.                 ,drive,&syscache);
  73. #endif
  74.                 }
  75.             if(flag==ADD) return  EACCDN;
  76.         if(flag==FIND || flag==KILL ) return inumtemp;
  77.             if(flag==POS) return entry*DIR_ENTRY_SIZE+zone*BLOCK_SIZE;
  78.         }
  79.             if(flag==ADD && lstfree==-1l && !inumtemp)
  80.                 lstfree=zone*BLOCK_SIZE+entry*DIR_ENTRY_SIZE;
  81.         }
  82.     }
  83.  
  84.     if(flag==ADD) {
  85.     dir_struct add[MAX_INCREMENT];
  86.     strncpy(tname,name,mfname );
  87.     tname[mfname]=0;
  88.     if(badname(tname)) return EACCDN;
  89.     if( do_trans(LWR_TOS,drive) ) Strlwr(tname);
  90.           strncpy(add[0].d_name,tname,mfname);
  91.     add[0].d_inum=0;
  92.     if(l_write(inum,lstfree,(long)(mfname+2),add,drive)
  93.             !=(mfname+2) ) return EACCDN;
  94.     return( lstfree==-1l ? rip.i_size : lstfree);
  95.     }
  96.     return EFILNF;
  97. }
  98.  
  99. /* Return '1' if 'name' has any illegal characters in it */
  100.  
  101. int badname(name)
  102. char *name;
  103. {
  104.     if(!*name)
  105.     {
  106.         DEBUG("Minixfs: Illegal null filename");
  107.         return 1;
  108.     }
  109.     for(;*name;name++) if(BADCHR(*name)) 
  110.     {
  111.         DEBUG("minixfs: Bad character in filename");
  112.         return 1;
  113.     }
  114.     return 0;
  115. }
  116.  
  117. /* Return '1' if dir2 is a parent of dir1 , otherwise 0 or negative error 
  118.  * number 
  119.  */
  120.  
  121. long is_parent(dir1,dir2,drive)
  122. unsigned dir1,dir2;
  123. int drive;
  124. {
  125.     long itemp=dir1;
  126.     for(;;)
  127.     {
  128.         if(itemp==dir2)
  129.         {
  130.             DEBUG("minixfs: invalid directory move");
  131.             return 1;
  132.         }
  133.         if(itemp==ROOT_INODE)break;
  134.         itemp=search_dir("..",itemp,drive,FIND);
  135.         if(itemp < 0)
  136.         {
  137.             ALERT("Couldn't trace inode %d back to root",dir1);
  138.             return EACCDN;
  139.         }    
  140.     }
  141.     return 0;
  142. }
  143.  
  144.  
  145.