tifile.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tifile.c (2592B)
---
     1 #include "stdinc.h"
     2 #include "dat.h"
     3 #include "fns.h"
     4 
     5 static char vcmagic[] = "venti config\n";
     6 
     7 enum {
     8         Maxconfig = 8 * 1024,
     9         Maglen = sizeof vcmagic - 1,
    10 };
    11 
    12 int
    13 readifile(IFile *f, char *name)
    14 {
    15         Part *p;
    16         ZBlock *b;
    17         u8int *z;
    18 
    19         p = initpart(name, OREAD);
    20         if(p == nil)
    21                 return -1;
    22         b = alloczblock(Maxconfig+1, 1, 0);
    23         if(b == nil){
    24                 seterr(EOk, "can't alloc for %s: %R", name);
    25                 return -1;
    26         }
    27         if(p->size > PartBlank){
    28                 /*
    29                  * this is likely a real venti partition, in which case we're
    30                  * looking for the config file stored as 8k at end of PartBlank.
    31                  */
    32                 if(readpart(p, PartBlank-Maxconfig, b->data, Maxconfig) < 0){
    33                         seterr(EOk, "can't read %s: %r", name);
    34                         freezblock(b);
    35                         freepart(p);
    36                         return -1;
    37                 }
    38                 b->data[Maxconfig] = '\0';
    39                 if(memcmp(b->data, vcmagic, Maglen) != 0){
    40                         seterr(EOk, "bad venti config magic in %s", name);
    41                         freezblock(b);
    42                         freepart(p);
    43                         return -1;
    44                 }
    45                 /*
    46                  * if we change b->data+b->_size, freezblock
    47                  * will blow an assertion, so don't.
    48                  */
    49                 b->data  += Maglen;
    50                 b->_size -= Maglen;
    51                 b->len   -= Maglen;
    52                 z = memchr(b->data, '\0', b->len);
    53                 if(z)
    54                         b->len = z - b->data;
    55         }else if(p->size > Maxconfig){
    56                 seterr(EOk, "config file is too large");
    57                 freepart(p);
    58                 freezblock(b);
    59                 return -1;
    60         }else{
    61                 freezblock(b);
    62                 b = readfile(name);
    63                 if(b == nil){
    64                         freepart(p);
    65                         return -1;
    66                 }
    67         }
    68         freepart(p);
    69         f->name = name;
    70         f->b = b;
    71         f->pos = 0;
    72         return 0;
    73 }
    74 
    75 void
    76 freeifile(IFile *f)
    77 {
    78         freezblock(f->b);
    79         f->b = nil;
    80         f->pos = 0;
    81 }
    82 
    83 int
    84 partifile(IFile *f, Part *part, u64int start, u32int size)
    85 {
    86         ZBlock *b;
    87 
    88         b = alloczblock(size, 0, part->blocksize);
    89         if(b == nil)
    90                 return -1;
    91         if(readpart(part, start, b->data, size) < 0){
    92                 seterr(EAdmin, "can't read %s: %r", part->name);
    93                 freezblock(b);
    94                 return -1;
    95         }
    96         f->name = part->name;
    97         f->b = b;
    98         f->pos = 0;
    99         return 0;
   100 }
   101 
   102 /*
   103  * return the next non-blank input line,
   104  * stripped of leading white space and with # comments eliminated
   105  */
   106 char*
   107 ifileline(IFile *f)
   108 {
   109         char *s, *e, *t;
   110         int c;
   111 
   112         for(;;){
   113                 s = (char*)&f->b->data[f->pos];
   114                 e = memchr(s, '\n', f->b->len - f->pos);
   115                 if(e == nil)
   116                         return nil;
   117                 *e++ = '\0';
   118                 f->pos = e - (char*)f->b->data;
   119                 t = strchr(s, '#');
   120                 if(t != nil)
   121                         *t = '\0';
   122                 for(; c = *s; s++)
   123                         if(c != ' ' && c != '\t' && c != '\r')
   124                                 return s;
   125         }
   126 }
   127 
   128 int
   129 ifilename(IFile *f, char *dst)
   130 {
   131         char *s;
   132 
   133         s = ifileline(f);
   134         if(s == nil || strlen(s) >= ANameSize)
   135                 return -1;
   136         namecp(dst, s);
   137         return 0;
   138 }
   139 
   140 int
   141 ifileu32int(IFile *f, u32int *r)
   142 {
   143         char *s;
   144 
   145         s = ifileline(f);
   146         if(s == nil)
   147                 return -1;
   148         return stru32int(s, r);
   149 }