00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "xurl.h"
00032
00033 static char *streallocat( char *psz_string, char *psz_to_append );
00034
00035 #ifndef HAVE_STRDUP
00036 static char *xurl_strdup( const char *psz_string );
00037 #else
00038 #define xurl_strdup strdup
00039 #endif
00040
00041 static char *XURL_FindHostname ( char *psz_url );
00042 static char *XURL_FindPath ( char *psz_url );
00043 static char *XURL_FindFragment ( char *psz_url );
00044
00045
00046 char *XURL_Join( char *psz_url1, char *psz_url2 )
00047 {
00048 if( XURL_IsAbsolute( psz_url1 ) )
00049 return XURL_Concat( psz_url1, psz_url2 );
00050 else
00051 return XURL_Concat( psz_url2, psz_url1 );
00052
00053 return NULL;
00054 }
00055
00056
00057
00058
00059
00060 char *XURL_Concat( char *psz_url, char *psz_append )
00061 {
00062 char *psz_return_value = NULL;
00063
00064 if( XURL_IsAbsolute( psz_append ) == XURL_TRUE )
00065 return strdup( psz_append );
00066
00067 if( XURL_IsAbsolute( psz_url ) )
00068 {
00069 if( XURL_HasAbsolutePath( psz_append ) )
00070 {
00071 char *psz_concat_url;
00072
00073 psz_concat_url = XURL_GetSchemeAndHostname( psz_url );
00074
00075 psz_concat_url = streallocat( psz_concat_url, psz_append );
00076 #ifdef XURL_DEBUG
00077 fprintf( stderr, "XURL_Concat: concat is \"%s\"\n",
00078 psz_concat_url );
00079 #endif
00080 psz_return_value = psz_concat_url;
00081 }
00082 else
00083 {
00084
00085 char *psz_new_url;
00086
00087
00088 psz_new_url = XURL_GetHead( psz_url );
00089 psz_new_url = streallocat( psz_new_url, psz_append );
00090
00091 psz_return_value = psz_new_url;
00092 }
00093 }
00094 else
00095 {
00096
00097 if( XURL_HasAbsolutePath( psz_append ) == XURL_FALSE )
00098 {
00099 char *psz_new_url = XURL_GetHead( psz_url );
00100
00101 psz_new_url = streallocat( psz_new_url, psz_append );
00102 psz_return_value = psz_new_url;
00103 }
00104 else
00105 {
00106
00107 psz_return_value = xurl_strdup( psz_append );
00108 }
00109 }
00110
00111 return psz_return_value;
00112 }
00113
00114
00115 XURL_Bool XURL_IsAbsolute( char *psz_url )
00116 {
00117 if( XURL_FindHostname( psz_url ) == NULL )
00118 {
00119 #ifdef XURL_DEBUG
00120 fprintf( stderr, "XURL_IsAbsolute(%s) returning false\n", psz_url );
00121 #endif
00122 return XURL_FALSE;
00123 }
00124 else
00125 {
00126 #ifdef XURL_DEBUG
00127 fprintf( stderr, "XURL_IsAbsolute(%s) returning true\n", psz_url );
00128 #endif
00129 return XURL_TRUE;
00130 }
00131 }
00132
00133
00134 XURL_Bool XURL_HasFragment( char *psz_url )
00135 {
00136 if( XURL_FindFragment( psz_url ) == NULL )
00137 return XURL_FALSE;
00138 else
00139 return XURL_TRUE;
00140 }
00141
00142
00143 char *XURL_FindHostname( char *psz_url )
00144 {
00145 char *psz_return_value = NULL;
00146
00147 char *psz_scheme_separator = strstr( psz_url, "://" );
00148 if( psz_scheme_separator != NULL)
00149 {
00150 char *psz_hostname = psz_scheme_separator + strlen( "://" );
00151 if( *psz_hostname != '\0') psz_return_value = psz_hostname;
00152
00153 #ifdef XURL_DEBUG
00154 fprintf( stderr, "XURL_FindHostname(%s): returning \"%s\"\n",
00155 psz_url, psz_return_value );
00156 #endif
00157 }
00158
00159 return psz_return_value;
00160 }
00161
00162
00163 XURL_Bool XURL_HasAbsolutePath( char *psz_url )
00164 {
00165 #ifdef XURL_WIN32_PATHING
00166 if( psz_url[0] == '/' || psz_url[0] == '\\' )
00167 #else
00168 if( psz_url[0] == '/' )
00169 #endif
00170 return XURL_TRUE;
00171 else
00172 return XURL_FALSE;
00173 }
00174
00175
00176 char *XURL_GetHostname( char *psz_url )
00177 {
00178 char *psz_return_value = NULL;
00179 char *psz_hostname = XURL_FindHostname( psz_url );
00180
00181 if( psz_hostname != NULL )
00182 {
00183 char *psz_new_hostname;
00184 size_t i_hostname_length;
00185
00186 char *psz_one_past_end_of_hostname = strchr( psz_hostname, '/' );
00187 if( psz_one_past_end_of_hostname != NULL)
00188 {
00189
00190
00191 i_hostname_length = psz_one_past_end_of_hostname -
00192 psz_hostname;
00193 }
00194 else
00195 {
00196
00197
00198 i_hostname_length = strlen( psz_url ) - ( psz_hostname - psz_url );
00199 }
00200
00201
00202 psz_new_hostname = xurl_malloc( i_hostname_length );
00203 if (psz_new_hostname == NULL) return NULL;
00204 strncpy( psz_new_hostname, psz_hostname, i_hostname_length );
00205
00206 #ifdef XURL_DEBUG
00207 fprintf (stderr, "XURL_GetHostname: psz_new_hostname is \"%s\"\n",
00208 psz_new_hostname );
00209 #endif
00210 psz_return_value = psz_new_hostname;
00211 }
00212 else
00213 {
00214
00215 return NULL;
00216 }
00217
00218 return psz_return_value;
00219 }
00220
00221
00222 char *XURL_GetSchemeAndHostname( char *psz_url )
00223 {
00224 char *psz_scheme, *psz_hostname, *psz_scheme_and_hostname;
00225
00226 psz_scheme = XURL_GetScheme( psz_url );
00227 if( psz_scheme == NULL ) return NULL;
00228
00229 psz_hostname = XURL_GetHostname( psz_url );
00230 if( psz_hostname == NULL ) return NULL;
00231
00232
00233 psz_scheme_and_hostname = xurl_malloc(
00234 strlen( psz_scheme ) + strlen( "://" ) +
00235 strlen( psz_hostname ) + 1);
00236 if( psz_scheme_and_hostname == NULL ) return NULL;
00237 (void) strcpy( psz_scheme_and_hostname, psz_scheme );
00238 (void) strcat( psz_scheme_and_hostname, "://" );
00239 (void) strcat( psz_scheme_and_hostname, psz_hostname );
00240
00241 if (psz_scheme_and_hostname == NULL ) return NULL;
00242 return psz_scheme_and_hostname;
00243 }
00244
00245 static
00246 char *XURL_FindFragment( char *psz_url )
00247 {
00248 char *pc_hash = NULL;
00249 char *pc_return_value = NULL;
00250
00251 pc_hash = strchr( psz_url, '#' );
00252 if( pc_hash != NULL )
00253 {
00254 pc_return_value = pc_hash;
00255 }
00256
00257 return pc_return_value;
00258 }
00259
00260
00261 char *XURL_FindQuery( char *psz_url )
00262 {
00263 char *pc_question_mark = NULL;
00264 char *pc_return_value = NULL;
00265
00266 pc_question_mark = strchr( psz_url, '?' );
00267 if( pc_question_mark != NULL )
00268 {
00269 pc_return_value = pc_question_mark;
00270 }
00271
00272 return pc_return_value;
00273 }
00274
00275
00276 char *XURL_GetScheme( char *psz_url )
00277 {
00278 char *psz_colon;
00279 size_t i_scheme_length;
00280 char *new_scheme;
00281
00282 if( XURL_IsAbsolute( psz_url ) == XURL_FALSE ) return strdup( "file" );
00283
00284
00285
00286 psz_colon = strchr( psz_url, ':' );
00287
00288 i_scheme_length = psz_colon - psz_url;
00289
00290 new_scheme = xurl_malloc( i_scheme_length );
00291 if( new_scheme == NULL ) return NULL;
00292
00293 strncpy( new_scheme, psz_url, i_scheme_length );
00294
00295 return new_scheme;
00296 }
00297
00298
00299 XURL_Bool XURL_IsFileURL( char *psz_url )
00300 {
00301 XURL_Bool b_return_value;
00302 char *psz_scheme = XURL_GetScheme( psz_url );
00303
00304 if( strcasecmp( psz_scheme, "file" ) == 0 )
00305 b_return_value = XURL_TRUE;
00306 else
00307 b_return_value = XURL_FALSE;
00308
00309 xurl_free( psz_scheme );
00310
00311 return b_return_value;
00312 }
00313
00314 #ifndef HAVE_STRDUP
00315 static
00316 char *xurl_strdup( const char *psz_string )
00317 {
00318 size_t i_length;
00319 char *psz_new_string;
00320
00321 if( !psz_string ) return NULL;
00322
00323 i_length = strlen( psz_string ) + 1;
00324 psz_new_string = (char *) xurl_malloc( i_length );
00325 if( psz_new_string == NULL ) return NULL;
00326
00327 memcpy( psz_new_string, psz_string, i_length );
00328
00329 return psz_new_string;
00330 }
00331 #endif
00332
00333 static
00334 char *XURL_FindPath( char *psz_url )
00335 {
00336 char *psz_return_value = NULL;
00337
00338 if( XURL_IsAbsolute( psz_url ) == XURL_TRUE )
00339 {
00340 char *psz_start_of_hostname = XURL_FindHostname( psz_url );
00341 if( psz_start_of_hostname != NULL )
00342 {
00343 char *psz_start_of_path = strchr( psz_start_of_hostname, '/' );
00344 psz_return_value = psz_start_of_path;
00345 }
00346 }
00347 else
00348 {
00349 if( XURL_HasAbsolutePath( psz_url ) == XURL_TRUE )
00350 {
00351 psz_return_value = psz_url;
00352 }
00353 else
00354 {
00355 return xurl_strdup (".");
00356 }
00357 }
00358
00359 return psz_return_value;
00360 }
00361
00362
00363 char *XURL_GetPath( char *psz_url )
00364 {
00365 char *psz_return_value = NULL;
00366 char *psz_path = NULL;
00367 char *pc_question_mark = NULL;
00368 char *pc_fragment = NULL;
00369
00370 psz_path = xurl_strdup( XURL_FindPath( psz_url ) );
00371 #ifdef XURL_DEBUG
00372 fprintf( stderr, "XURL_GetPath: XURL_FindPath returning \"%s\"\n",
00373 psz_path );
00374 #endif
00375 psz_return_value = psz_path;
00376
00377 pc_question_mark = XURL_FindQuery( psz_path );
00378 if( pc_question_mark != NULL )
00379 {
00380 int i_path_length = pc_question_mark - psz_path;
00381 *( psz_path + i_path_length ) = '\0';
00382 }
00383
00384 pc_fragment = XURL_FindFragment( psz_path );
00385 if( pc_fragment != NULL )
00386 {
00387 #ifdef XURL_DEBUG
00388 fprintf( stderr, "XURL_GetPath: XURL_FindFragment returned \"%s\"\n",
00389 pc_fragment );
00390 #endif
00391 int i_path_length = pc_fragment - psz_path;
00392 *( psz_path + i_path_length ) = '\0';
00393 }
00394
00395 #ifdef XURL_DEBUG
00396 fprintf( stderr, "XURL_GetPath returning \"%s\"\n", psz_return_value );
00397 #endif
00398
00399 return psz_return_value;
00400 }
00401
00402
00403 char *XURL_GetHead( const char *psz_path )
00404 {
00405 char *psz_path_head;
00406 char *pc_last_slash;
00407
00408
00409 #ifdef XURL_WIN32_PATHING
00410
00411 pc_last_slash = strrchr( psz_path, '\\' );
00412 if( pc_last_slash == NULL )
00413 pc_last_slash = strrchr( psz_path, '/' );
00414 #else
00415 pc_last_slash = strrchr( psz_path, '/' );
00416 #endif
00417 if( pc_last_slash == NULL )
00418 {
00419 psz_path_head = xurl_strdup( psz_path );
00420 }
00421 else
00422 {
00423 size_t i_characters_until_last_slash;
00424
00425 i_characters_until_last_slash = pc_last_slash - psz_path;
00426 psz_path_head = malloc(
00427 ( i_characters_until_last_slash + 1 ) * sizeof(char) );
00428 (void) strncpy( psz_path_head, psz_path,
00429 i_characters_until_last_slash + 1 );
00430
00431
00432 *(psz_path_head +
00433 i_characters_until_last_slash) = '\0';
00434 }
00435
00436
00437 streallocat( psz_path_head, "/" );
00438
00439 return psz_path_head;
00440 }
00441
00442
00443 char *XURL_GetWithoutFragment( char *psz_url )
00444 {
00445 char *psz_return_value = NULL;
00446 char *psz_fragment;
00447
00448 psz_fragment = XURL_FindFragment( psz_url );
00449 if( psz_fragment == NULL )
00450 {
00451 psz_return_value = xurl_strdup( psz_url );
00452 }
00453 else
00454 {
00455 size_t i_pre_fragment_length;
00456 char *psz_without_fragment;
00457
00458 i_pre_fragment_length = psz_fragment - psz_url;
00459
00460 psz_without_fragment = xurl_malloc( i_pre_fragment_length + 1 );
00461 if( psz_without_fragment == NULL )
00462 {
00463 psz_return_value = NULL;
00464 }
00465 else
00466 {
00467 memcpy( psz_without_fragment, psz_url, i_pre_fragment_length );
00468 *( psz_without_fragment + i_pre_fragment_length ) = '\0';
00469 psz_return_value = psz_without_fragment;
00470 }
00471 }
00472
00473 return psz_return_value;
00474 }
00475
00476 static
00477 char *streallocat( char *psz_string, char *psz_to_append )
00478 {
00479 size_t i_new_string_length = strlen( psz_string ) +
00480 strlen( psz_to_append ) + 1;
00481
00482 psz_string = (char *) realloc( psz_string, i_new_string_length );
00483
00484 return strcat( psz_string, psz_to_append );
00485 }
00486