diff options
Diffstat (limited to 'src/android.c')
| -rw-r--r-- | src/android.c | 90 |
1 files changed, 72 insertions, 18 deletions
diff --git a/src/android.c b/src/android.c index f59c0d9e5d2..92aab548180 100644 --- a/src/android.c +++ b/src/android.c | |||
| @@ -1045,19 +1045,72 @@ android_user_full_name (struct passwd *pw) | |||
| 1045 | #endif | 1045 | #endif |
| 1046 | } | 1046 | } |
| 1047 | 1047 | ||
| 1048 | |||
| 1049 | |||
| 1050 | /* Determine whether or not the specified file NAME describes a file | ||
| 1051 | in the directory DIR, which should be an absolute file name. NAME | ||
| 1052 | must be in canonical form. | ||
| 1053 | |||
| 1054 | Value is NULL if not. Otherwise, it is a pointer to the first | ||
| 1055 | character in NAME after the part containing DIR and its trailing | ||
| 1056 | directory separator. */ | ||
| 1057 | |||
| 1058 | const char * | ||
| 1059 | android_is_special_directory (const char *name, const char *dir) | ||
| 1060 | { | ||
| 1061 | size_t len; | ||
| 1062 | |||
| 1063 | /* Compare up to strlen (DIR) bytes of NAME with DIR. */ | ||
| 1064 | |||
| 1065 | len = strlen (dir); | ||
| 1066 | if (strncmp (name, dir, len)) | ||
| 1067 | return NULL; | ||
| 1068 | |||
| 1069 | /* Now see if the character of NAME after len is either a directory | ||
| 1070 | separator or a terminating NULL. */ | ||
| 1071 | |||
| 1072 | name += len; | ||
| 1073 | switch (*name) | ||
| 1074 | { | ||
| 1075 | case '\0': | ||
| 1076 | /* Return the empty string if this is the end of the file | ||
| 1077 | name. */ | ||
| 1078 | return name; | ||
| 1079 | |||
| 1080 | case '/': | ||
| 1081 | /* Return NAME (with the separator removed) if it describes a | ||
| 1082 | file. */ | ||
| 1083 | return name + 1; | ||
| 1084 | |||
| 1085 | default: | ||
| 1086 | /* The file name doesn't match. */ | ||
| 1087 | return NULL; | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | |||
| 1048 | /* Given a real file name, return the part that describes its asset | 1091 | /* Given a real file name, return the part that describes its asset |
| 1049 | path, or NULL if it is not an asset. */ | 1092 | path, or NULL if it is not an asset. |
| 1093 | |||
| 1094 | If FILENAME contains only `/assets', return `/' to indicate the | ||
| 1095 | root of the assets hierarchy. */ | ||
| 1050 | 1096 | ||
| 1051 | static const char * | 1097 | static const char * |
| 1052 | android_get_asset_name (const char *filename) | 1098 | android_get_asset_name (const char *filename) |
| 1053 | { | 1099 | { |
| 1054 | if (!strcmp (filename, "/assets") || !strcmp (filename, "/assets/")) | 1100 | const char *name; |
| 1055 | return "/"; | ||
| 1056 | 1101 | ||
| 1057 | if (!strncmp (filename, "/assets/", sizeof "/assets/" - 1)) | 1102 | name = android_is_special_directory (filename, "/assets"); |
| 1058 | return filename + (sizeof "/assets/" - 1); | ||
| 1059 | 1103 | ||
| 1060 | return NULL; | 1104 | if (!name) |
| 1105 | return NULL; | ||
| 1106 | |||
| 1107 | /* If NAME is empty, return /. Otherwise, return the name relative | ||
| 1108 | to /assets/. */ | ||
| 1109 | |||
| 1110 | if (*name) | ||
| 1111 | return name; | ||
| 1112 | |||
| 1113 | return "/"; | ||
| 1061 | } | 1114 | } |
| 1062 | 1115 | ||
| 1063 | /* Return whether or not the specified FILENAME actually resolves to a | 1116 | /* Return whether or not the specified FILENAME actually resolves to a |
| @@ -1072,9 +1125,9 @@ android_content_name_p (const char *filename) | |||
| 1072 | if (android_api_level < 19) | 1125 | if (android_api_level < 19) |
| 1073 | return false; | 1126 | return false; |
| 1074 | 1127 | ||
| 1075 | return (!strcmp (filename, "/content") | 1128 | return (android_is_special_directory (filename, |
| 1076 | || !strncmp (filename, "/content/", | 1129 | "/content") |
| 1077 | sizeof "/content/" - 1)); | 1130 | != NULL); |
| 1078 | } | 1131 | } |
| 1079 | 1132 | ||
| 1080 | /* Return the content URI corresponding to a `/content' file name, | 1133 | /* Return the content URI corresponding to a `/content' file name, |
| @@ -1091,20 +1144,21 @@ android_get_content_name (const char *filename) | |||
| 1091 | 1144 | ||
| 1092 | n = PATH_MAX; | 1145 | n = PATH_MAX; |
| 1093 | 1146 | ||
| 1094 | /* First handle content ``URIs'' without a provider. */ | 1147 | /* Find the file name described if it starts with `/content'. If |
| 1148 | just the directory is described, return content://. */ | ||
| 1095 | 1149 | ||
| 1096 | if (!strcmp (filename, "/content") | 1150 | filename = android_is_special_directory (filename, "/content"); |
| 1097 | || !strcmp (filename, "/content/")) | ||
| 1098 | return "content://"; | ||
| 1099 | 1151 | ||
| 1100 | /* Next handle ordinary file names. */ | 1152 | if (!filename) |
| 1101 | |||
| 1102 | if (strncmp (filename, "/content/", sizeof "/content/" - 1)) | ||
| 1103 | return NULL; | 1153 | return NULL; |
| 1104 | 1154 | ||
| 1105 | /* Forward past the first directory specifying the schema. */ | 1155 | if (!*filename) |
| 1156 | return "content://"; | ||
| 1157 | |||
| 1158 | /* Now copy FILENAME into a buffer and convert it into a content | ||
| 1159 | URI. */ | ||
| 1106 | 1160 | ||
| 1107 | copy = xstrdup (filename + sizeof "/content"); | 1161 | copy = xstrdup (filename); |
| 1108 | token = saveptr = NULL; | 1162 | token = saveptr = NULL; |
| 1109 | head = stpcpy (buffer, "content:/"); | 1163 | head = stpcpy (buffer, "content:/"); |
| 1110 | 1164 | ||