options.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * linux/fs/hfsplus/options.c
  3. *
  4. * Copyright (C) 2001
  5. * Brad Boyer (flar@allandria.com)
  6. * (C) 2003 Ardis Technologies <roman@ardistech.com>
  7. *
  8. * Option parsing
  9. */
  10. #include <linux/string.h>
  11. #include <linux/kernel.h>
  12. #include <linux/sched.h>
  13. #include <linux/parser.h>
  14. #include <linux/nls.h>
  15. #include "hfsplus_fs.h"
  16. enum {
  17. opt_creator, opt_type,
  18. opt_umask, opt_uid, opt_gid,
  19. opt_part, opt_session, opt_nls,
  20. opt_nodecompose, opt_decompose,
  21. opt_err
  22. };
  23. static match_table_t tokens = {
  24. { opt_creator, "creator=%s" },
  25. { opt_type, "type=%s" },
  26. { opt_umask, "umask=%o" },
  27. { opt_uid, "uid=%u" },
  28. { opt_gid, "gid=%u" },
  29. { opt_part, "part=%u" },
  30. { opt_session, "session=%u" },
  31. { opt_nls, "nls=%s" },
  32. { opt_decompose, "decompose" },
  33. { opt_nodecompose, "nodecompose" },
  34. { opt_err, NULL }
  35. };
  36. /* Initialize an options object to reasonable defaults */
  37. void fill_defaults(struct hfsplus_sb_info *opts)
  38. {
  39. if (!opts)
  40. return;
  41. opts->creator = HFSPLUS_DEF_CR_TYPE;
  42. opts->type = HFSPLUS_DEF_CR_TYPE;
  43. opts->umask = current->fs->umask;
  44. opts->uid = current->uid;
  45. opts->gid = current->gid;
  46. opts->part = -1;
  47. opts->session = -1;
  48. }
  49. /* convert a "four byte character" to a 32 bit int with error checks */
  50. static inline int match_fourchar(substring_t *arg, u32 *result)
  51. {
  52. if (arg->to - arg->from != 4)
  53. return -EINVAL;
  54. memcpy(result, arg->from, 4);
  55. return 0;
  56. }
  57. /* Parse options from mount. Returns 0 on failure */
  58. /* input is the options passed to mount() as a string */
  59. int parse_options(char *input, struct hfsplus_sb_info *sbi)
  60. {
  61. char *p;
  62. substring_t args[MAX_OPT_ARGS];
  63. int tmp, token;
  64. if (!input)
  65. goto done;
  66. while ((p = strsep(&input, ",")) != NULL) {
  67. if (!*p)
  68. continue;
  69. token = match_token(p, tokens, args);
  70. switch (token) {
  71. case opt_creator:
  72. if (match_fourchar(&args[0], &sbi->creator)) {
  73. printk("HFS+-fs: creator requires a 4 character value\n");
  74. return 0;
  75. }
  76. break;
  77. case opt_type:
  78. if (match_fourchar(&args[0], &sbi->type)) {
  79. printk("HFS+-fs: type requires a 4 character value\n");
  80. return 0;
  81. }
  82. break;
  83. case opt_umask:
  84. if (match_octal(&args[0], &tmp)) {
  85. printk("HFS+-fs: umask requires a value\n");
  86. return 0;
  87. }
  88. sbi->umask = (umode_t)tmp;
  89. break;
  90. case opt_uid:
  91. if (match_int(&args[0], &tmp)) {
  92. printk("HFS+-fs: uid requires an argument\n");
  93. return 0;
  94. }
  95. sbi->uid = (uid_t)tmp;
  96. break;
  97. case opt_gid:
  98. if (match_int(&args[0], &tmp)) {
  99. printk("HFS+-fs: gid requires an argument\n");
  100. return 0;
  101. }
  102. sbi->gid = (gid_t)tmp;
  103. break;
  104. case opt_part:
  105. if (match_int(&args[0], &sbi->part)) {
  106. printk("HFS+-fs: part requires an argument\n");
  107. return 0;
  108. }
  109. break;
  110. case opt_session:
  111. if (match_int(&args[0], &sbi->session)) {
  112. printk("HFS+-fs: session requires an argument\n");
  113. return 0;
  114. }
  115. break;
  116. case opt_nls:
  117. if (sbi->nls) {
  118. printk("HFS+-fs: unable to change nls mapping\n");
  119. return 0;
  120. }
  121. p = match_strdup(&args[0]);
  122. sbi->nls = load_nls(p);
  123. if (!sbi->nls) {
  124. printk("HFS+-fs: unable to load nls mapping \"%s\"\n", p);
  125. kfree(p);
  126. return 0;
  127. }
  128. kfree(p);
  129. break;
  130. case opt_decompose:
  131. sbi->flags &= ~HFSPLUS_SB_NODECOMPOSE;
  132. break;
  133. case opt_nodecompose:
  134. sbi->flags |= HFSPLUS_SB_NODECOMPOSE;
  135. break;
  136. default:
  137. return 0;
  138. }
  139. }
  140. done:
  141. if (!sbi->nls) {
  142. /* try utf8 first, as this is the old default behaviour */
  143. sbi->nls = load_nls("utf8");
  144. if (!sbi->nls)
  145. sbi->nls = load_nls_default();
  146. if (!sbi->nls)
  147. return 0;
  148. }
  149. return 1;
  150. }