jchar.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <libsec.h>
  5. #include "iso9660.h"
  6. char*
  7. jolietstring(uchar *buf, int len)
  8. {
  9. char *p, *q;
  10. int i;
  11. Rune *rp;
  12. rp = emalloc(sizeof(Rune)*(len/2+1));
  13. p = emalloc(UTFmax*(len/2+1));
  14. for(i=0; i<len/2; i++)
  15. rp[i] = (buf[2*i]<<8) | buf[2*i+1];
  16. rp[i] = (Rune)'\0';
  17. snprint(p, UTFmax*(len/2+1), "%S", rp);
  18. q = atom(p);
  19. free(p);
  20. return q;
  21. }
  22. /*
  23. * Joliet name validity check
  24. *
  25. * Joliet names have length at most 128 bytes (64 runes),
  26. * and cannot contain '*', '/', ':', ';', '?', or '\'.
  27. */
  28. int
  29. isjolietfrog(Rune r)
  30. {
  31. return r==L'*' || r==L'/' || r==L':'
  32. || r==';' || r=='?' || r=='\\';
  33. }
  34. int
  35. isbadjoliet(char *s)
  36. {
  37. Rune r[256], *p;
  38. if(utflen(s) > 64)
  39. return 1;
  40. strtorune(r, s);
  41. for(p=r; *p; p++)
  42. if(isjolietfrog(*p))
  43. return 1;
  44. return 0;
  45. }
  46. /*
  47. * Joliet name comparison
  48. *
  49. * The standard algorithm is the ISO9660 algorithm but
  50. * on the encoded Runes. Runes are encoded in big endian
  51. * format, so we can just use runecmp.
  52. *
  53. * Padding is with zeros, but that still doesn't affect us.
  54. */
  55. static Rune emptystring[] = { (Rune)0 };
  56. int
  57. jolietcmp(const void *va, const void *vb)
  58. {
  59. int i;
  60. Rune s1[256], s2[256], *b1, *b2, *e1, *e2; /*BUG*/
  61. const Direc *a, *b;
  62. a = va;
  63. b = vb;
  64. b1 = strtorune(s1, a->confname);
  65. b2 = strtorune(s2, b->confname);
  66. if((e1 = runechr(b1, (Rune)'.')) != nil)
  67. *e1++ = '\0';
  68. else
  69. e1 = emptystring;
  70. if((e2 = runechr(b2, (Rune)'.')) != nil)
  71. *e2++ = '\0';
  72. else
  73. e2 = emptystring;
  74. if((i = runecmp(b1, b2)) != 0)
  75. return i;
  76. return runecmp(e1, e2);
  77. }
  78. /*
  79. * Write a Joliet secondary volume descriptor.
  80. */
  81. void
  82. Cputjolietsvd(Cdimg *cd, Cdinfo info)
  83. {
  84. Cputc(cd, 2); /* secondary volume descriptor */
  85. Cputs(cd, "CD001", 5); /* standard identifier */
  86. Cputc(cd, 1); /* volume descriptor version */
  87. Cputc(cd, 0); /* unused */
  88. Cputrscvt(cd, "Joliet Plan 9", 32); /* system identifier */
  89. Cputrscvt(cd, info.volumename, 32); /* volume identifier */
  90. Crepeat(cd, 0, 8); /* unused */
  91. Cputn(cd, 0, 4); /* volume space size */
  92. Cputc(cd, 0x25); /* escape sequences: UCS-2 Level 2 */
  93. Cputc(cd, 0x2F);
  94. Cputc(cd, 0x43);
  95. Crepeat(cd, 0, 29);
  96. Cputn(cd, 1, 2); /* volume set size */
  97. Cputn(cd, 1, 2); /* volume sequence number */
  98. Cputn(cd, Blocksize, 2); /* logical block size */
  99. Cputn(cd, 0, 4); /* path table size */
  100. Cputnl(cd, 0, 4); /* location of Lpath */
  101. Cputnl(cd, 0, 4); /* location of optional Lpath */
  102. Cputnm(cd, 0, 4); /* location of Mpath */
  103. Cputnm(cd, 0, 4); /* location of optional Mpath */
  104. Cputjolietdir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */
  105. Cputrscvt(cd, info.volumeset, 128); /* volume set identifier */
  106. Cputrscvt(cd, info.publisher, 128); /* publisher identifier */
  107. Cputrscvt(cd, info.preparer, 128); /* data preparer identifier */
  108. Cputrscvt(cd, info.application, 128); /* application identifier */
  109. Cputrscvt(cd, "", 37); /* copyright notice */
  110. Cputrscvt(cd, "", 37); /* abstract */
  111. Cputrscvt(cd, "", 37); /* bibliographic file */
  112. Cputdate1(cd, now); /* volume creation date */
  113. Cputdate1(cd, now); /* volume modification date */
  114. Cputdate1(cd, 0); /* volume expiration date */
  115. Cputdate1(cd, 0); /* volume effective date */
  116. Cputc(cd, 1); /* file structure version */
  117. Cpadblock(cd);
  118. }