plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

ichar.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 }