]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/disk/9660/conform.c
fix real cause of iso name truncation
[plan9front.git] / sys / src / cmd / disk / 9660 / conform.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <libsec.h>
5 #include <ctype.h>
6 #include "iso9660.h"
7
8 /*
9  * We keep an array sorted by bad atom pointer.
10  * The theory is that since we don't free memory very often,
11  * the array will be mostly sorted already and insertions will
12  * usually be near the end, so we won't spend much time
13  * keeping it sorted.
14  */
15
16 /*
17  * Binary search a Tx list.
18  * If no entry is found, return a pointer to
19  * where a new such entry would go.
20  */
21 static Tx*
22 txsearch(char *atom, Tx *t, int n)
23 {
24         while(n > 0) {
25                 if(atom < t[n/2].bad)
26                         n = n/2;
27                 else if(atom > t[n/2].bad) {
28                         t += n/2+1;
29                         n -= (n/2+1);
30                 } else
31                         return &t[n/2];
32         }
33         return t;
34 }
35
36 void
37 addtx(char *b, char *g)
38 {
39         Tx *t;
40         Conform *c;
41
42         if(map == nil)
43                 map = emalloc(sizeof(*map));
44         c = map;
45
46         if(c->nt%32 == 0)
47                 c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0]));
48         t = txsearch(b, c->t, c->nt);
49         if(t < c->t+c->nt && t->bad == b) {
50                 fprint(2, "warning: duplicate entry for %s in _conform.map\n", b);
51                 return;
52         }
53
54         if(t != c->t+c->nt)
55                 memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx));
56         t->bad = b;
57         t->good = g;
58         c->nt++;
59 }
60
61 char*
62 conform(char *s, int isdir)
63 {
64         Tx *t;
65         char buf[10], *g;
66         Conform *c;
67
68         c = map;
69         s = atom(s);
70         if(c){
71                 t = txsearch(s, c->t, c->nt);
72                 if(t < c->t+c->nt && t->bad == s)
73                         return t->good;
74         }
75
76         sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0);
77         g = atom(buf);
78         addtx(s, g);
79         return g;
80 }
81
82 #ifdef NOTUSED
83 static int
84 isalldigit(char *s)
85 {
86         while(*s)
87                 if(!isdigit(*s++))
88                         return 0;
89         return 1;
90 }
91 #endif
92
93 static int
94 goodcmp(const void *va, const void *vb)
95 {
96         Tx *a, *b;
97
98         a = (Tx*)va;
99         b = (Tx*)vb;
100         return strcmp(a->good, b->good);
101 }
102
103 static int
104 badatomcmp(const void *va, const void *vb)
105 {
106         Tx *a, *b;
107
108         a = (Tx*)va;
109         b = (Tx*)vb;
110         if(a->good < b->good)
111                 return -1;
112         if(a->good > b->good)
113                 return 1;
114         return 0;
115 }
116
117 void
118 wrconform(Cdimg *cd, int n, ulong *pblock, uvlong *plength)
119 {
120         char buf[1024];
121         int i;
122         Conform *c;
123
124         c = map;
125         *pblock = cd->nextblock;
126         if(c==nil || n==c->nt){
127                 *plength = 0;
128                 return;
129         }
130
131         Cwseek(cd, (vlong)cd->nextblock * Blocksize);
132         qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp);
133         for(i=n; i<c->nt; i++) {
134                 snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad);
135                 Cwrite(cd, buf, strlen(buf));
136         }
137         qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp);
138         *plength = Cwoffset(cd) - (vlong)*pblock * Blocksize;
139         chat("write _conform.map at %lud+%llud\n", *pblock, *plength);
140         Cpadblock(cd);
141 }