tichar.c - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       tichar.c (4831B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <libsec.h>
            5 #include <ctype.h>
            6 
            7 #include "iso9660.h"
            8 
            9 /*
           10  * ISO 9660 file names must be uppercase, digits, or underscore.
           11  * We use lowercase, digits, and underscore, translating lower to upper
           12  * in mkisostring, and upper to lower in isostring.
           13  * Files with uppercase letters in their names are thus nonconforming.
           14  * Conforming files also must have a basename
           15  * at most 8 letters and at most one suffix of at most 3 letters.
           16  */
           17 char*
           18 isostring(uchar *buf, int len)
           19 {
           20         char *p, *q;
           21 
           22         p = emalloc(len+1);
           23         memmove(p, buf, len);
           24         p[len] = '\0';
           25         while(len > 0 && p[len-1] == ' ')
           26                 p[--len] = '\0';
           27         for(q=p; *q; q++)
           28                 *q = tolower((uchar)*q);
           29         q = atom(p);
           30         free(p);
           31         return q;
           32 }
           33 
           34 int
           35 isisofrog(char c)
           36 {
           37         if(c >= '0' && c <= '9')
           38                 return 0;
           39         if(c >= 'a' && c <= 'z')
           40                 return 0;
           41         if(c == '_')
           42                 return 0;
           43 
           44         return 1;
           45 }
           46 
           47 int
           48 isbadiso9660(char *s)
           49 {
           50         char *p, *q;
           51         int i;
           52 
           53         if((p = strchr(s, '.')) != nil) {
           54                 if(p-s > 8)
           55                         return 1;
           56                 for(q=s; q<p; q++)
           57                         if(isisofrog(*q))
           58                                 return 1;
           59                 if(strlen(p+1) > 3)
           60                         return 1;
           61                 for(q=p+1; *q; q++)
           62                         if(isisofrog(*q))
           63                                 return 1;
           64         } else {
           65                 if(strlen(s) > 8)
           66                         return 1;
           67                 for(q=s; *q; q++)
           68                         if(isisofrog(*q))
           69                                 return 1;
           70 
           71                 /*
           72                  * we rename files of the form [FD]dddddd
           73                  * so they don't interfere with us.
           74                  */
           75                 if(strlen(s) == 7 && (s[0] == 'D' || s[0] == 'F')) {
           76                         for(i=1; i<7; i++)
           77                                 if(s[i] < '0' || s[i] > '9')
           78                                         break;
           79                         if(i == 7)
           80                                 return 1;
           81                 }
           82         }
           83         return 0;
           84 }
           85 
           86 /*
           87  * ISO9660 name comparison
           88  *
           89  * The standard algorithm is as follows:
           90  *   Take the filenames without extensions, pad the shorter with 0x20s (spaces),
           91  *   and do strcmp.  If they are equal, go on.
           92  *   Take the extensions, pad the shorter with 0x20s (spaces),
           93  *   and do strcmp.  If they are equal, go on.
           94  *   Compare the version numbers.
           95  *
           96  * Since Plan 9 names are not allowed to contain characters 0x00-0x1F,
           97  * the padded comparisons are equivalent to using strcmp directly.
           98  * We still need to handle the base and extension differently,
           99  * so that .foo sorts before !foo.foo.
          100  */
          101 int
          102 isocmp(const void *va, const void *vb)
          103 {
          104         int i;
          105         char s1[32], s2[32], *b1, *b2, *e1, *e2;
          106         const Direc *a, *b;
          107 
          108         a = va;
          109         b = vb;
          110 
          111         strecpy(s1, s1+sizeof s1, a->confname);
          112         b1 = s1;
          113         strecpy(s2, s2+sizeof s2, b->confname);
          114         b2 = s2;
          115         if((e1 = strchr(b1, '.')) != nil)
          116                 *e1++ = '\0';
          117         else
          118                 e1 = "";
          119         if((e2 = strchr(b2, '.')) != nil)
          120                 *e2++ = '\0';
          121         else
          122                 e2 = "";
          123 
          124         if((i = strcmp(b1, b2)) != 0)
          125                 return i;
          126 
          127         return strcmp(e1, e2);
          128 }
          129 
          130 static char*
          131 mkisostring(char *isobuf, int n, char *s)
          132 {
          133         char *p, *q, *eq;
          134 
          135         eq = isobuf+n;
          136         for(p=s, q=isobuf; *p && q < eq; p++)
          137                 if('a' <= *p && *p <= 'z')
          138                         *q++ = *p+'A'-'a';
          139                 else
          140                         *q++ = *p;
          141 
          142         while(q < eq)
          143                 *q++ = ' ';
          144 
          145         return isobuf;
          146 }
          147 
          148 void
          149 Cputisopvd(Cdimg *cd, Cdinfo info)
          150 {
          151         char buf[130];
          152 
          153         Cputc(cd, 1);                                /* primary volume descriptor */
          154         Cputs(cd, "CD001", 5);                        /* standard identifier */
          155         Cputc(cd, 1);                                /* volume descriptor version */
          156         Cputc(cd, 0);                                /* unused */
          157 
          158         assert(~info.flags & (CDplan9|CDrockridge));
          159 
          160         /* system identifier */
          161         strcpy(buf, "");
          162         if(info.flags & CDplan9)
          163                 strcat(buf, "plan 9 ");
          164         if(info.flags & CDrockridge)
          165                 strcat(buf, "rrip ");
          166         if(info.flags & CDbootable)
          167                 strcat(buf, "boot ");
          168         if(info.flags & CDconform)
          169                 strcat(buf, "iso9660");
          170         else
          171                 strcat(buf, "utf8");
          172 
          173         struprcpy(buf, buf);
          174         Cputs(cd, buf, 32);
          175 
          176         Cputs(cd, mkisostring(buf, 32, info.volumename), 32);                        /* volume identifier */
          177 
          178         Crepeat(cd, 0, 8);                                /* unused */
          179         Cputn(cd, 0, 4);                                /* volume space size */
          180         Crepeat(cd, 0, 32);                                /* unused */
          181         Cputn(cd, 1, 2);                                /* volume set size */
          182         Cputn(cd, 1, 2);                                /* volume sequence number */
          183         Cputn(cd, Blocksize, 2);                        /* logical block size */
          184         Cputn(cd, 0, 4);                                /* path table size */
          185         Cputnl(cd, 0, 4);                                /* location of Lpath */
          186         Cputnl(cd, 0, 4);                                /* location of optional Lpath */
          187         Cputnm(cd, 0, 4);                                /* location of Mpath */
          188         Cputnm(cd, 0, 4);                                /* location of optional Mpath */
          189         Cputisodir(cd, nil, DTroot, 1, Cwoffset(cd));                        /* root directory */
          190 
          191         Cputs(cd, mkisostring(buf, 128, info.volumeset), 128);                /* volume set identifier */
          192         Cputs(cd, mkisostring(buf, 128, info.publisher), 128);                        /* publisher identifier */
          193         Cputs(cd, mkisostring(buf, 128, info.preparer), 128);                        /* data preparer identifier */
          194         Cputs(cd, mkisostring(buf, 128, info.application), 128);                /* application identifier */
          195 
          196         Cputs(cd, "", 37);                        /* copyright notice */
          197         Cputs(cd, "", 37);                        /* abstract */
          198         Cputs(cd, "", 37);                        /* bibliographic file */
          199         Cputdate1(cd, now);                                /* volume creation date */
          200         Cputdate1(cd, now);                                /* volume modification date */
          201         Cputdate1(cd, 0);                                /* volume expiration date */
          202         Cputdate1(cd, 0);                                /* volume effective date */
          203         Cputc(cd, 1);                                /* file structure version */
          204         Cpadblock(cd);
          205 }