fs_getopt.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file fs/fs_getopt.c
  18. * @brief helper functions for command-line argument processing
  19. * @author Igor Wronsky, Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_fs_service.h"
  23. #include "gnunet_getopt_lib.h"
  24. #include "fs_api.h"
  25. /* ******************** command-line option parsing API ******************** */
  26. /**
  27. * Command-line option parser function that allows the user
  28. * to specify one or more '-k' options with keywords. Each
  29. * specified keyword will be added to the URI. A pointer to
  30. * the URI must be passed as the "scls" argument.
  31. *
  32. * @param ctx command line processor context
  33. * @param scls must be of type "struct GNUNET_FS_Uri **"
  34. * @param option name of the option (typically 'k')
  35. * @param value command line argument given
  36. * @return #GNUNET_OK on success
  37. */
  38. static int
  39. getopt_set_keywords (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  40. void *scls,
  41. const char *option,
  42. const char *value)
  43. {
  44. struct GNUNET_FS_Uri **uri = scls;
  45. struct GNUNET_FS_Uri *u = *uri;
  46. char *val;
  47. size_t slen;
  48. if (NULL == u)
  49. {
  50. u = GNUNET_new (struct GNUNET_FS_Uri);
  51. *uri = u;
  52. u->type = GNUNET_FS_URI_KSK;
  53. u->data.ksk.keywordCount = 0;
  54. u->data.ksk.keywords = NULL;
  55. }
  56. else
  57. {
  58. GNUNET_assert (GNUNET_FS_URI_KSK == u->type);
  59. }
  60. slen = strlen (value);
  61. if (0 == slen)
  62. return GNUNET_SYSERR; /* cannot be empty */
  63. if (value[0] == '+')
  64. {
  65. /* simply preserve the "mandatory" flag */
  66. if (slen < 2)
  67. return GNUNET_SYSERR; /* empty keywords not allowed */
  68. if ((value[1] == '"') && (slen > 3) && (value[slen - 1] == '"'))
  69. {
  70. /* remove the quotes, keep the '+' */
  71. val = GNUNET_malloc (slen - 1);
  72. val[0] = '+';
  73. GNUNET_memcpy (&val[1],
  74. &value[2],
  75. slen - 3);
  76. val[slen - 2] = '\0';
  77. }
  78. else
  79. {
  80. /* no quotes, just keep the '+' */
  81. val = GNUNET_strdup (value);
  82. }
  83. }
  84. else
  85. {
  86. if ((value[0] == '"') && (slen > 2) && (value[slen - 1] == '"'))
  87. {
  88. /* remove the quotes, add a space */
  89. val = GNUNET_malloc (slen);
  90. val[0] = ' ';
  91. GNUNET_memcpy (&val[1],
  92. &value[1],
  93. slen - 2);
  94. val[slen - 1] = '\0';
  95. }
  96. else
  97. {
  98. /* add a space to indicate "not mandatory" */
  99. val = GNUNET_malloc (slen + 2);
  100. strcpy (val, " ");
  101. strcat (val, value);
  102. }
  103. }
  104. GNUNET_array_append (u->data.ksk.keywords,
  105. u->data.ksk.keywordCount,
  106. val);
  107. return GNUNET_OK;
  108. }
  109. /**
  110. * Allow user to specify keywords.
  111. *
  112. * @param shortName short name of the option
  113. * @param name long name of the option
  114. * @param argumentHelp help text for the option argument
  115. * @param description long help text for the option
  116. * @param[out] topKeywords set to the desired value
  117. */
  118. struct GNUNET_GETOPT_CommandLineOption
  119. GNUNET_FS_GETOPT_KEYWORDS (char shortName,
  120. const char *name,
  121. const char *argumentHelp,
  122. const char *description,
  123. struct GNUNET_FS_Uri **topKeywords)
  124. {
  125. struct GNUNET_GETOPT_CommandLineOption clo = {
  126. .shortName = shortName,
  127. .name = name,
  128. .argumentHelp = argumentHelp,
  129. .description = description,
  130. .require_argument = 1,
  131. .processor = &getopt_set_keywords,
  132. .scls = (void *) topKeywords
  133. };
  134. return clo;
  135. }
  136. /**
  137. * Command-line option parser function that allows the user to specify
  138. * one or more '-m' options with metadata. Each specified entry of
  139. * the form "type=value" will be added to the metadata. A pointer to
  140. * the metadata must be passed as the "scls" argument.
  141. *
  142. * @param ctx command line processor context
  143. * @param scls must be of type "struct GNUNET_MetaData **"
  144. * @param option name of the option (typically 'k')
  145. * @param value command line argument given
  146. * @return #GNUNET_OK on success
  147. */
  148. static int
  149. getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
  150. void *scls,
  151. const char *option,
  152. const char *value)
  153. {
  154. struct GNUNET_CONTAINER_MetaData **mm = scls;
  155. #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
  156. enum EXTRACTOR_MetaType type;
  157. const char *typename;
  158. const char *typename_i18n;
  159. #endif
  160. struct GNUNET_CONTAINER_MetaData *meta;
  161. char *tmp;
  162. meta = *mm;
  163. if (meta == NULL)
  164. {
  165. meta = GNUNET_CONTAINER_meta_data_create ();
  166. *mm = meta;
  167. }
  168. /* Use GNUNET_STRINGS_get_utf8_args() in main() to acquire utf-8-encoded
  169. * commandline arguments, so that the following line is not needed.
  170. */
  171. /*tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), locale_charset ());*/
  172. tmp = GNUNET_strdup (value);
  173. #if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
  174. type = EXTRACTOR_metatype_get_max ();
  175. while (type > 0)
  176. {
  177. type--;
  178. typename = EXTRACTOR_metatype_to_string (type);
  179. typename_i18n = dgettext (LIBEXTRACTOR_GETTEXT_DOMAIN, typename);
  180. if ((strlen (tmp) >= strlen (typename) + 1) &&
  181. (tmp[strlen (typename)] == ':') &&
  182. (0 == strncmp (typename, tmp, strlen (typename))))
  183. {
  184. GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", type,
  185. EXTRACTOR_METAFORMAT_UTF8,
  186. "text/plain",
  187. &tmp[strlen (typename) + 1],
  188. strlen (&tmp[strlen (typename) + 1])
  189. + 1);
  190. GNUNET_free (tmp);
  191. tmp = NULL;
  192. break;
  193. }
  194. if ((strlen (tmp) >= strlen (typename_i18n) + 1) &&
  195. (tmp[strlen (typename_i18n)] == ':') &&
  196. (0 == strncmp (typename_i18n, tmp, strlen (typename_i18n))))
  197. {
  198. GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", type,
  199. EXTRACTOR_METAFORMAT_UTF8,
  200. "text/plain",
  201. &tmp[strlen (typename_i18n) + 1],
  202. strlen (&tmp
  203. [strlen (typename_i18n) + 1])
  204. + 1);
  205. GNUNET_free (tmp);
  206. tmp = NULL;
  207. break;
  208. }
  209. }
  210. #endif
  211. if (NULL != tmp)
  212. {
  213. GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>",
  214. EXTRACTOR_METATYPE_UNKNOWN,
  215. EXTRACTOR_METAFORMAT_UTF8, "text/plain",
  216. tmp, strlen (tmp) + 1);
  217. GNUNET_free (tmp);
  218. printf (_
  219. (
  220. "Unknown metadata type in metadata option `%s'. Using metadata type `unknown' instead.\n"),
  221. value);
  222. }
  223. return GNUNET_OK;
  224. }
  225. /**
  226. * Allow user to specify metadata.
  227. *
  228. * @param shortName short name of the option
  229. * @param name long name of the option
  230. * @param argumentHelp help text for the option argument
  231. * @param description long help text for the option
  232. * @param[out] metadata set to the desired value
  233. */
  234. struct GNUNET_GETOPT_CommandLineOption
  235. GNUNET_FS_GETOPT_METADATA (char shortName,
  236. const char *name,
  237. const char *argumentHelp,
  238. const char *description,
  239. struct GNUNET_CONTAINER_MetaData **meta)
  240. {
  241. struct GNUNET_GETOPT_CommandLineOption clo = {
  242. .shortName = shortName,
  243. .name = name,
  244. .argumentHelp = argumentHelp,
  245. .description = description,
  246. .require_argument = 1,
  247. .processor = &getopt_set_metadata,
  248. .scls = (void *) meta
  249. };
  250. return clo;
  251. }
  252. /* end of fs_getopt.c */