aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_strings_lib.h58
-rw-r--r--src/util/strings.c183
2 files changed, 241 insertions, 0 deletions
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 4fb007707..385b6c042 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -256,6 +256,64 @@ GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen,
256} 256}
257#endif 257#endif
258 258
259enum GNUNET_STRINGS_FilenameCheck
260{
261 GNUNET_STRINGS_CHECK_EXISTS = 0x00000001,
262 GNUNET_STRINGS_CHECK_IS_DIRECTORY = 0x00000002,
263 GNUNET_STRINGS_CHECK_IS_LINK = 0x00000004,
264 GNUNET_STRINGS_CHECK_IS_ABSOLUTE = 0x00000008
265};
266
267/**
268 * Parse a path that might be an URI.
269 *
270 * @param path path to parse. Must be NULL-terminated.
271 * @param scheme_part a pointer to 'char *' where a pointer to a string that
272 * represents the URI scheme will be stored. Can be NULL. The string is
273 * allocated by the function, and should be freed by GNUNET_free() when
274 * it is no longer needed.
275 * @param path_part a pointer to 'const char *' where a pointer to the path
276 * part of the URI will be stored. Can be NULL. Points to the same block
277 * of memory as 'path', and thus must not be freed. Might point to '\0',
278 * if path part is zero-length.
279 * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not
280 * an URI, '* scheme_part' and '*path_part' will remain unchanged
281 * (if they weren't NULL).
282 */
283int
284GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part,
285 const char **path_part);
286
287/**
288 * Check whether @filename is absolute or not, and if it's an URI
289 *
290 * @param filename filename to check
291 * @param can_be_uri GNUNET_YES to check for being URI, GNUNET_NO - to
292 * assume it's not URI
293 * @param r_is_uri a pointer to an int that is set to GNUNET_YES if @filename
294 * is URI and to GNUNET_NO otherwise. Can be NULL. If @can_be_uri is
295 * not GNUNET_YES, *r_is_uri is set to GNUNET_NO.
296 * @param r_uri a pointer to a char * that is set to a pointer to URI scheme.
297 * The string is allocated by the function, and should be freed with
298 * GNUNET_free (). Can be NULL.
299 * @return GNUNET_YES if @filaneme is absolute, GNUNET_NO otherwise.
300 */
301int
302GNUNET_STRINGS_path_is_absolute (const char *filename, int can_be_uri,
303 int *r_is_uri, char **r_uri_scheme);
304
305/**
306 * Perform @checks on @filename
307 *
308 * @param filename file to check
309 * @param checks checks to perform
310 * @return GNUNET_YES if all @checks pass, GNUNET_NO if at least one of them
311 * fails, GNUNET_SYSERR when a check can't be performed
312 */
313int
314GNUNET_STRINGS_check_filename (const char *filename,
315 enum GNUNET_STRINGS_FilenameCheck checks);
316
259 317
260/* ifndef GNUNET_UTIL_STRING_H */ 318/* ifndef GNUNET_UTIL_STRING_H */
261#endif 319#endif
diff --git a/src/util/strings.c b/src/util/strings.c
index 2b8b955c8..abc763b88 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -766,5 +766,188 @@ GNUNET_STRINGS_string_to_data (const char *enc, size_t enclen,
766} 766}
767 767
768 768
769/**
770 * Parse a path that might be an URI.
771 *
772 * @param path path to parse. Must be NULL-terminated.
773 * @param scheme_part a pointer to 'char *' where a pointer to a string that
774 * represents the URI scheme will be stored. Can be NULL. The string is
775 * allocated by the function, and should be freed by GNUNET_free() when
776 * it is no longer needed.
777 * @param path_part a pointer to 'const char *' where a pointer to the path
778 * part of the URI will be stored. Can be NULL. Points to the same block
779 * of memory as 'path', and thus must not be freed. Might point to '\0',
780 * if path part is zero-length.
781 * @return GNUNET_YES if it's an URI, GNUNET_NO otherwise. If 'path' is not
782 * an URI, '* scheme_part' and '*path_part' will remain unchanged
783 * (if they weren't NULL).
784 */
785int
786GNUNET_STRINGS_parse_uri (const char *path, char **scheme_part,
787 const char **path_part)
788{
789 size_t len;
790 int i, end;
791 int pp_state = 0;
792 const char *post_scheme_part = NULL;
793 len = strlen (path);
794 for (end = 0, i = 0; !end && i < len; i++)
795 {
796 switch (pp_state)
797 {
798 case 0:
799 if (path[i] == ':' && i > 0)
800 {
801 pp_state += 1;
802 continue;
803 }
804 if (!((path[i] >= 'A' && path[i] <= 'Z') || (path[i] >= 'a' && path[i] <= 'z')
805 || (path[i] >= '0' && path[i] <= '9') || path[i] == '+' || path[i] == '-'
806 || (path[i] == '.')))
807 end = 1;
808 break;
809 case 1:
810 case 2:
811 if (path[i] == '/')
812 {
813 pp_state += 1;
814 continue;
815 }
816 end = 1;
817 break;
818 case 3:
819 post_scheme_part = &path[i];
820 end = 1;
821 break;
822 default:
823 end = 1;
824 }
825 }
826 if (post_scheme_part == NULL)
827 return GNUNET_NO;
828 if (scheme_part)
829 {
830 *scheme_part = GNUNET_malloc (post_scheme_part - path + 1);
831 memcpy (*scheme_part, path, post_scheme_part - path);
832 (*scheme_part)[post_scheme_part - path] = '\0';
833 }
834 if (path_part)
835 *path_part = post_scheme_part;
836 return GNUNET_YES;
837}
838
839
840/**
841 * Check whether @filename is absolute or not, and if it's an URI
842 *
843 * @param filename filename to check
844 * @param can_be_uri GNUNET_YES to check for being URI, GNUNET_NO - to
845 * assume it's not URI
846 * @param r_is_uri a pointer to an int that is set to GNUNET_YES if @filename
847 * is URI and to GNUNET_NO otherwise. Can be NULL. If @can_be_uri is
848 * not GNUNET_YES, *r_is_uri is set to GNUNET_NO.
849 * @param r_uri a pointer to a char * that is set to a pointer to URI scheme.
850 * The string is allocated by the function, and should be freed with
851 * GNUNET_free (). Can be NULL.
852 * @return GNUNET_YES if @filaneme is absolute, GNUNET_NO otherwise.
853 */
854int
855GNUNET_STRINGS_path_is_absolute (const char *filename, int can_be_uri,
856 int *r_is_uri, char **r_uri_scheme)
857{
858#if WINDOWS
859 size_t len;
860#endif
861 const char *post_scheme_path;
862 int is_uri;
863 char * uri;
864 /* consider POSIX paths to be absolute too, even on W32,
865 * as plibc expansion will fix them for us.
866 */
867 if (filename[0] == '/')
868 return GNUNET_YES;
869 if (can_be_uri)
870 {
871 is_uri = GNUNET_STRINGS_parse_uri (filename, &uri, &post_scheme_path);
872 if (r_is_uri)
873 *r_is_uri = is_uri;
874 if (is_uri)
875 {
876 if (r_uri_scheme)
877 *r_uri_scheme = uri;
878 else
879 GNUNET_free_non_null (uri);
880#if WINDOWS
881 len = strlen(post_scheme_path);
882 /* Special check for file:///c:/blah
883 * We want to parse 'c:/', not '/c:/'
884 */
885 if (post_scheme_path[0] == '/' && len >= 3 && post_scheme_path[2] == ':')
886 post_scheme_path = &post_scheme_path[1];
887#endif
888 return GNUNET_STRINGS_path_is_absolute (post_scheme_path, GNUNET_NO, NULL, NULL);
889 }
890 }
891 else
892 {
893 is_uri = GNUNET_NO;
894 if (r_is_uri)
895 *r_is_uri = GNUNET_NO;
896 }
897#if WINDOWS
898 len = strlen (filename);
899 if (len >= 3 &&
900 ((filename[0] >= 'A' && filename[0] <= 'Z')
901 || (filename[0] >= 'a' && filename[0] <= 'z'))
902 && filename[1] == ':' && (filename[2] == '/' || filename[2] == '\\'))
903 return GNUNET_YES;
904#endif
905 return GNUNET_NO;
906}
907
908#if MINGW
909#define _IFMT 0170000 /* type of file */
910#define _IFLNK 0120000 /* symbolic link */
911#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
912#endif
913
914/**
915 * Perform @checks on @filename
916 *
917 * @param filename file to check
918 * @param checks checks to perform
919 * @return GNUNET_YES if all @checks pass, GNUNET_NO if at least one of them
920 * fails, GNUNET_SYSERR when a check can't be performed
921 */
922int
923GNUNET_STRINGS_check_filename (const char *filename,
924 enum GNUNET_STRINGS_FilenameCheck checks)
925{
926 struct stat st;
927 if (filename == NULL || filename[0] == '\0')
928 return GNUNET_SYSERR;
929 if (checks & GNUNET_STRINGS_CHECK_IS_ABSOLUTE)
930 if (!GNUNET_STRINGS_path_is_absolute (filename, GNUNET_NO, NULL, NULL))
931 return GNUNET_NO;
932 if (checks & (GNUNET_STRINGS_CHECK_EXISTS
933 | GNUNET_STRINGS_CHECK_IS_DIRECTORY
934 | GNUNET_STRINGS_CHECK_IS_LINK))
935 {
936 if (STAT (filename, &st))
937 {
938 if (checks & GNUNET_STRINGS_CHECK_EXISTS)
939 return GNUNET_NO;
940 else
941 return GNUNET_SYSERR;
942 }
943 }
944 if (checks & GNUNET_STRINGS_CHECK_IS_DIRECTORY)
945 if (!S_ISDIR (st.st_mode))
946 return GNUNET_NO;
947 if (checks & GNUNET_STRINGS_CHECK_IS_LINK)
948 if (!S_ISLNK (st.st_mode))
949 return GNUNET_NO;
950 return GNUNET_YES;
951}
769 952
770/* end of strings.c */ 953/* end of strings.c */