PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/sys/vfs/isofs/cd9660/cd9660_util.c

https://bitbucket.org/cooljeanius/dragonflybsd
C | 210 lines | 145 code | 7 blank | 58 comment | 53 complexity | 9aacfeb989780b86338b5bd3a386239c MD5 | raw file
  1. /*-
  2. * Copyright (c) 1994
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley
  6. * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
  7. * Support code is derived from software contributed to Berkeley
  8. * by Atsushi Murai (amurai@spec.co.jp). Joliet support was added by
  9. * Joachim Kuebart (joki@kuebart.stuttgart.netsurf.de).
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 3. All advertising materials mentioning features or use of this software
  20. * must display the following acknowledgement:
  21. * This product includes software developed by the University of
  22. * California, Berkeley and its contributors.
  23. * 4. Neither the name of the University nor the names of its contributors
  24. * may be used to endorse or promote products derived from this software
  25. * without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37. * SUCH DAMAGE.
  38. *
  39. * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
  40. * $FreeBSD: src/sys/isofs/cd9660/cd9660_util.c,v 1.13.2.1 2001/02/27 12:36:34 sobomax Exp $
  41. */
  42. #include <sys/param.h>
  43. #include <sys/mount.h>
  44. #include <sys/vnode.h>
  45. #include <sys/iconv.h>
  46. #include "iso.h"
  47. #include "cd9660_mount.h"
  48. extern struct iconv_functions *cd9660_iconv;
  49. /*
  50. * Get one character out of an iso filename
  51. * Obey joliet_level
  52. * Return number of bytes consumed
  53. */
  54. int
  55. isochar(u_char *isofn, u_char *isoend, int joliet_level, u_short *c,
  56. int *clen, int flags, void *handle)
  57. {
  58. size_t i, j, len;
  59. char inbuf[3], outbuf[3], *inp, *outp;
  60. *c = *isofn++;
  61. if (clen) *clen = 1;
  62. if (joliet_level == 0 || isofn == isoend)
  63. /* (00) and (01) are one byte in Joliet, too */
  64. return 1;
  65. if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
  66. i = j = len = 2;
  67. inbuf[0]=(char)*(isofn - 1);
  68. inbuf[1]=(char)*isofn;
  69. inbuf[2]='\0';
  70. inp = inbuf;
  71. outp = outbuf;
  72. cd9660_iconv->convchr(handle, (const char **)(void *)&inp,
  73. &i, &outp, &j);
  74. len -= j;
  75. if (clen) *clen = len;
  76. *c = '\0';
  77. while(len--)
  78. *c |= (*(outp - len - 1) & 0xff) << (len << 3);
  79. } else {
  80. switch (*c) {
  81. default:
  82. *c = '?';
  83. break;
  84. case '\0':
  85. *c = *isofn;
  86. break;
  87. }
  88. }
  89. return 2;
  90. }
  91. /*
  92. * translate and compare a filename
  93. * returns (fn - isofn)
  94. * Note: Version number plus ';' may be omitted.
  95. */
  96. int
  97. isofncmp(u_char *fn, int fnlen, u_char *isofn, int isolen, int joliet_level,
  98. int flags, void *handle, void *lhandle)
  99. {
  100. int i, j;
  101. u_short c, d;
  102. u_char *fnend = fn + fnlen, *isoend = isofn + isolen;
  103. for (; fn < fnend; ) {
  104. d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle);
  105. if (isofn == isoend)
  106. return d;
  107. isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
  108. if (c == ';') {
  109. if (d != ';')
  110. return d;
  111. for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') {
  112. if (*fn < '0' || *fn > '9') {
  113. return -1;
  114. }
  115. }
  116. for (j = 0; isofn != isoend; j = j * 10 + c - '0')
  117. isofn += isochar(isofn, isoend,
  118. joliet_level, &c,
  119. NULL, flags, handle);
  120. return i - j;
  121. }
  122. if (c != d) {
  123. if (c >= 'A' && c <= 'Z') {
  124. if (c + ('a' - 'A') != d) {
  125. if (d >= 'a' && d <= 'z')
  126. return d - ('a' - 'A') - c;
  127. else
  128. return d - c;
  129. }
  130. } else
  131. return d - c;
  132. }
  133. }
  134. if (isofn != isoend) {
  135. isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle);
  136. switch (c) {
  137. default:
  138. return -c;
  139. case '.':
  140. if (isofn != isoend) {
  141. isochar(isofn, isoend, joliet_level, &c,
  142. NULL, flags, handle);
  143. if (c == ';')
  144. return 0;
  145. }
  146. return -1;
  147. case ';':
  148. return 0;
  149. }
  150. }
  151. return 0;
  152. }
  153. /*
  154. * translate a filename of length > 0
  155. */
  156. void
  157. isofntrans(u_char *infn, int infnlen, u_char *outfn, u_short *outfnlen, int original,
  158. int assoc, int joliet_level, int flags, void *handle)
  159. {
  160. u_short c, d = '\0';
  161. u_char *outp = outfn, *infnend = infn + infnlen;
  162. int clen;
  163. if (assoc) {
  164. *outp++ = ASSOCCHAR;
  165. }
  166. for (; infn != infnend; ) {
  167. infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle);
  168. if (!original && !joliet_level && c >= 'A' && c <= 'Z')
  169. c += ('a' - 'A');
  170. else if (!original && c == ';') {
  171. outp -= (d == '.');
  172. break;
  173. }
  174. d = c;
  175. while(clen--)
  176. *outp++ = c >> (clen << 3);
  177. }
  178. *outfnlen = outp - outfn;
  179. }
  180. /*
  181. * same as sgetrune(3)
  182. */
  183. u_short
  184. sgetrune(const char *string, size_t n, char const **result,
  185. int flags, void *handle)
  186. {
  187. size_t i, j, len;
  188. char outbuf[3], *outp;
  189. u_short c = '\0';
  190. len = i = (n < 2) ? n : 2;
  191. j = 2;
  192. outp = outbuf;
  193. if (flags & ISOFSMNT_KICONV && cd9660_iconv) {
  194. cd9660_iconv->convchr(handle, &string, &i, &outp, &j);
  195. len -= i;
  196. } else {
  197. len = 1;
  198. string++;
  199. }
  200. if (result) *result = string;
  201. while(len--) c |= (*(string - len - 1) & 0xff) << (len << 3);
  202. return (c);
  203. }