Print this page
8485 Remove set but unused variables in usr/src/cmd
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/ldap/common/fileurl.c
+++ new/usr/src/cmd/ldap/common/fileurl.c
1 1 /*
2 + * Copyright 2017 Gary Mills
2 3 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 4 * Use is subject to license terms.
4 5 */
5 6
6 7 /*
7 8 * The contents of this file are subject to the Netscape Public
8 9 * License Version 1.1 (the "License"); you may not use this file
9 10 * except in compliance with the License. You may obtain a copy of
10 11 * the License at http://www.mozilla.org/NPL/
11 12 *
12 13 * Software distributed under the License is distributed on an "AS
13 14 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 15 * implied. See the License for the specific language governing
15 16 * rights and limitations under the License.
16 17 *
17 18 * The Original Code is Mozilla Communicator client code, released
18 19 * March 31, 1998.
19 20 *
20 21 * The Initial Developer of the Original Code is Netscape
21 22 * Communications Corporation. Portions created by Netscape are
22 23 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
23 24 * Rights Reserved.
24 25 *
25 26 * Contributor(s):
26 27 */
27 28
28 29 /*
29 30 * LDAP tools fileurl.c -- functions for handling file URLs.
30 31 * Used by ldapmodify.
31 32 */
32 33
33 34 #include "ldaptool.h"
34 35 #include "fileurl.h"
35 36 #include <ctype.h> /* for isalpha() */
36 37 #ifdef SOLARIS_LDAP_CMD
37 38 #include <locale.h>
38 39 #endif /* SOLARIS_LDAP_CMD */
39 40
40 41 #ifndef SOLARIS_LDAP_CMD
41 42 #define gettext(s) s
42 43 #endif
43 44
44 45 static int str_starts_with( const char *s, char *prefix );
45 46 static void hex_unescape( char *s );
46 47 static int unhex( char c );
47 48 static void strcpy_escaped_and_convert( char *s1, char *s2 );
48 49 static int berval_from_file( const char *path, struct berval *bvp,
49 50 int reporterrs );
50 51
51 52 /*
52 53 * Convert a file URL to a local path.
53 54 *
54 55 * If successful, LDAPTOOL_FILEURL_SUCCESS is returned and *localpathp is
55 56 * set point to an allocated string. If not, an different LDAPTOOL_FILEURL_
56 57 * error code is returned.
57 58 *
58 59 * See RFCs 1738 and 2396 for a specification for file URLs... but
59 60 * Netscape Navigator seems to be a bit more lenient in what it will
60 61 * accept, especially on Windows).
61 62 *
62 63 * This function parses file URLs of these three forms:
63 64 *
64 65 * file:///path
65 66 * file:/path
66 67 * file://localhost/path
67 68 * file://host/path (rejected with a ...NONLOCAL error)
68 69 *
69 70 * On Windows, we convert leading drive letters of the form C| to C:
70 71 * and if a drive letter is present we strip off the slash that precedes
71 72 * path. Otherwise, the leading slash is returned.
72 73 *
73 74 */
74 75 int
75 76 ldaptool_fileurl2path( const char *fileurl, char **localpathp )
76 77 {
77 78 const char *path;
78 79 char *pathcopy;
79 80
80 81 /*
81 82 * Make sure this is a file URL we can handle.
82 83 */
83 84 if ( !str_starts_with( fileurl, "file:" )) {
84 85 return( LDAPTOOL_FILEURL_NOTAFILEURL );
85 86 }
86 87
87 88 path = fileurl + 5; /* skip past "file:" scheme prefix */
88 89
89 90 if ( *path != '/' ) {
90 91 return( LDAPTOOL_FILEURL_MISSINGPATH );
91 92 }
92 93
93 94 ++path; /* skip past '/' at end of "file:/" */
94 95
95 96 if ( *path == '/' ) {
96 97 ++path; /* remainder is now host/path or /path */
97 98 if ( *path != '/' ) {
98 99 /*
99 100 * Make sure it is for the local host.
100 101 */
101 102 if ( str_starts_with( path, "localhost/" )) {
102 103 path += 9;
103 104 } else {
104 105 return( LDAPTOOL_FILEURL_NONLOCAL );
105 106 }
106 107 }
107 108 } else { /* URL is of the form file:/path */
108 109 --path;
109 110 }
110 111
111 112 /*
112 113 * The remainder is now of the form /path. On Windows, skip past the
113 114 * leading slash if a drive letter is present.
114 115 */
115 116 #ifdef _WINDOWS
116 117 if ( isalpha( path[1] ) && ( path[2] == '|' || path[2] == ':' )) {
117 118 ++path;
118 119 }
119 120 #endif /* _WINDOWS */
120 121
121 122 /*
122 123 * Duplicate the path so we can safely alter it.
123 124 * Unescape any %HH sequences.
124 125 */
125 126 if (( pathcopy = strdup( path )) == NULL ) {
126 127 return( LDAPTOOL_FILEURL_NOMEMORY );
127 128 }
128 129 hex_unescape( pathcopy );
129 130
130 131 #ifdef _WINDOWS
131 132 /*
132 133 * Convert forward slashes to backslashes for Windows. Also,
133 134 * if we see a drive letter / vertical bar combination (e.g., c|)
134 135 * at the beginning of the path, replace the '|' with a ':'.
135 136 */
136 137 {
137 138 char *p;
138 139
139 140 for ( p = pathcopy; *p != '\0'; ++p ) {
140 141 if ( *p == '/' ) {
141 142 *p = '\\';
142 143 }
143 144 }
144 145 }
145 146
146 147 if ( isalpha( pathcopy[0] ) && pathcopy[1] == '|' ) {
147 148 pathcopy[1] = ':';
148 149 }
149 150 #endif /* _WINDOWS */
150 151
151 152 *localpathp = pathcopy;
152 153 return( LDAPTOOL_FILEURL_SUCCESS );
153 154 }
154 155
155 156
156 157 /*
157 158 * Convert a local path to a file URL.
158 159 *
159 160 * If successful, LDAPTOOL_FILEURL_SUCCESS is returned and *urlp is
160 161 * set point to an allocated string. If not, an different LDAPTOOL_FILEURL_
161 162 * error code is returned. At present, the only possible error is
162 163 * LDAPTOOL_FILEURL_NOMEMORY.
163 164 *
164 165 * This function produces file URLs of the form file:path.
165 166 *
166 167 * On Windows, we convert leading drive letters to C|.
167 168 *
168 169 */
169 170 int
170 171 ldaptool_path2fileurl( char *path, char **urlp )
171 172 {
172 173 char *p, *url, *prefix ="file:";
173 174
174 175 if ( NULL == path ) {
175 176 path = "/";
176 177 }
177 178
178 179 /*
179 180 * Allocate space for the URL, taking into account that path may
180 181 * expand during the hex escaping process.
181 182 */
182 183 if (( url = malloc( strlen( prefix ) + 3 * strlen( path ) + 1 )) == NULL ) {
183 184 return( LDAPTOOL_FILEURL_NOMEMORY );
184 185 }
185 186
186 187 strcpy( url, prefix );
187 188 p = url + strlen( prefix );
188 189
189 190 #ifdef _WINDOWS
190 191 /*
191 192 * On Windows, convert leading drive letters (e.g., C:) to the correct URL
192 193 * syntax (e.g., C|).
193 194 */
194 195 if ( isalpha( path[0] ) && path[1] == ':' ) {
195 196 *p++ = path[0];
196 197 *p++ = '|';
197 198 path += 2;
198 199 *p = '\0';
199 200 }
200 201 #endif /* _WINDOWS */
201 202
202 203 /*
203 204 * Append the path, encoding any URL-special characters using the %HH
204 205 * convention.
205 206 * On Windows, convert backwards slashes in the path to forward ones.
206 207 */
207 208 strcpy_escaped_and_convert( p, path );
208 209
209 210 *urlp = url;
210 211 return( LDAPTOOL_FILEURL_SUCCESS );
211 212 }
212 213
213 214
214 215 /*
215 216 * Populate *bvp from "value" of length "vlen."
216 217 *
217 218 * If recognize_url_syntax is non-zero, :<fileurl is recognized.
218 219 * If always_try_file is recognized and no file URL was found, an
219 220 * attempt is made to stat and read the value as if it were the name
220 221 * of a file.
221 222 *
222 223 * If reporterrs is non-zero, specific error messages are printed to
223 224 * stderr.
224 225 *
225 226 * If successful, LDAPTOOL_FILEURL_SUCCESS is returned and bvp->bv_len
226 227 * and bvp->bv_val are set (the latter is set to malloc'd memory).
227 228 * Upon failure, a different LDAPTOOL_FILEURL_ error code is returned.
228 229 */
229 230 int
230 231 ldaptool_berval_from_ldif_value( const char *value, int vlen,
231 232 struct berval *bvp, int recognize_url_syntax, int always_try_file,
232 233 int reporterrs )
233 234 {
234 235 int rc = LDAPTOOL_FILEURL_SUCCESS; /* optimistic */
235 236 const char *url = NULL;
236 237 struct stat fstats;
237 238
238 239 /* recognize "attr :< url" syntax if LDIF version is >= 1 */
239 240
240 241 #ifdef notdef
241 242 if ( ldaptool_verbose ) {
242 243 fprintf( stderr, gettext("%s: ldaptool_berval_from_ldif_value: value: %s\n"),
243 244 ldaptool_progname, value);
244 245 }
245 246 #endif
246 247
247 248 if ( recognize_url_syntax && *value == '<' ) {
248 249 for ( url = value + 1; isspace( *url ); ++url ) {
249 250 ; /* NULL */
250 251 }
251 252
252 253 if (strlen(url) > 7 && strncasecmp(url, "file://", 7) != 0) {
253 254 /*
254 255 * We only support file:// URLs for now.
255 256 */
256 257 url = NULL;
257 258 }
258 259 }
259 260
260 261 if ( NULL != url ) {
261 262 char *path;
262 263
263 264 rc = ldaptool_fileurl2path( url, &path );
264 265 switch( rc ) {
265 266 case LDAPTOOL_FILEURL_NOTAFILEURL:
266 267 if ( reporterrs ) fprintf( stderr, gettext("%s: unsupported URL \"%s\";"
267 268 " use a file:// URL instead.\n"), ldaptool_progname, url );
268 269 break;
269 270
270 271 case LDAPTOOL_FILEURL_MISSINGPATH:
271 272 if ( reporterrs ) fprintf( stderr,
272 273 gettext("%s: unable to process URL \"%s\" --"
273 274 " missing path.\n"), ldaptool_progname, url );
274 275 break;
275 276
276 277 case LDAPTOOL_FILEURL_NONLOCAL:
277 278 if ( reporterrs ) fprintf( stderr,
278 279 gettext("%s: unable to process URL \"%s\" -- only"
279 280 " local file:// URLs are supported.\n"),
280 281 ldaptool_progname, url );
281 282 break;
282 283
283 284 case LDAPTOOL_FILEURL_NOMEMORY:
284 285 if ( reporterrs ) perror( "ldaptool_fileurl2path" );
285 286 break;
286 287
287 288 case LDAPTOOL_FILEURL_SUCCESS:
288 289 if ( stat( path, &fstats ) != 0 ) {
289 290 if ( reporterrs ) perror( path );
290 291 } else if (S_ISDIR(fstats.st_mode)) {
291 292 if ( reporterrs ) fprintf( stderr,
292 293 gettext("%s: %s is a directory, not a file\n"),
293 294 ldaptool_progname, path );
294 295 rc = LDAPTOOL_FILEURL_FILEIOERROR;
295 296 } else {
296 297 rc = berval_from_file( path, bvp, reporterrs );
297 298 }
298 299 free( path );
299 300 break;
300 301
301 302 default:
302 303 if ( reporterrs ) fprintf( stderr,
303 304 gettext("%s: unable to process URL \"%s\""
304 305 " -- unknown error\n"), ldaptool_progname, url );
305 306 }
306 307 } else if ( always_try_file && (stat( value, &fstats ) == 0) &&
307 308 !S_ISDIR(fstats.st_mode)) { /* get value from file */
308 309 rc = berval_from_file( value, bvp, reporterrs );
309 310 } else {
310 311 bvp->bv_len = vlen;
311 312 if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
312 313 if ( reporterrs ) perror( "malloc" );
313 314 rc = LDAPTOOL_FILEURL_NOMEMORY;
314 315 } else {
315 316 SAFEMEMCPY( bvp->bv_val, value, vlen );
316 317 bvp->bv_val[ vlen ] = '\0';
317 318 }
318 319 }
319 320
320 321 return( rc );
321 322 }
322 323
323 324
324 325 /*
325 326 * Map an LDAPTOOL_FILEURL_ error code to an LDAP error code (crude).
326 327 */
327 328 int
328 329 ldaptool_fileurlerr2ldaperr( int lderr )
329 330 {
330 331 int rc;
331 332
332 333 switch( lderr ) {
333 334 case LDAPTOOL_FILEURL_SUCCESS:
334 335 rc = LDAP_SUCCESS;
335 336 break;
336 337 case LDAPTOOL_FILEURL_NOMEMORY:
337 338 rc = LDAP_NO_MEMORY;
338 339 break;
339 340 default:
340 341 rc = LDAP_PARAM_ERROR;
341 342 }
342 343
343 344 return( rc );
344 345 }
345 346
346 347
347 348 /*
348 349 * Populate *bvp with the contents of the file named by "path".
349 350 *
350 351 * If reporterrs is non-zero, specific error messages are printed to
351 352 * stderr.
352 353 *
↓ open down ↓ |
341 lines elided |
↑ open up ↑ |
353 354 * If successful, LDAPTOOL_FILEURL_SUCCESS is returned and bvp->bv_len
354 355 * and bvp->bv_val are set (the latter is set to malloc'd memory).
355 356 * Upon failure, a different LDAPTOOL_FILEURL_ error code is returned.
356 357 */
357 358
358 359 static int
359 360 berval_from_file( const char *path, struct berval *bvp, int reporterrs )
360 361 {
361 362 FILE *fp;
362 363 long rlen;
363 - int eof;
364 364 #if defined( XP_WIN32 )
365 365 char mode[20] = "r+b";
366 366 #else
367 367 char mode[20] = "r";
368 368 #endif
369 369
370 370 #ifdef SOLARIS_LDAP_CMD
371 371 if (( fp = fopen( path, mode )) == NULL ) {
372 372 #else
373 373 if (( fp = ldaptool_open_file( path, mode )) == NULL ) {
374 374 #endif /* SOLARIS_LDAP_CMD */
375 375 if ( reporterrs ) perror( path );
376 376 return( LDAPTOOL_FILEURL_FILEIOERROR );
377 377 }
378 378
379 379 if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
380 380 if ( reporterrs ) perror( path );
381 381 fclose( fp );
382 382 return( LDAPTOOL_FILEURL_FILEIOERROR );
383 383 }
384 384
385 385 bvp->bv_len = ftell( fp );
386 386
387 387 if (( bvp->bv_val = (char *)malloc( bvp->bv_len + 1 )) == NULL ) {
388 388 if ( reporterrs ) perror( "malloc" );
389 389 fclose( fp );
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
390 390 return( LDAPTOOL_FILEURL_NOMEMORY );
391 391 }
392 392
393 393 if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {
394 394 if ( reporterrs ) perror( path );
395 395 fclose( fp );
396 396 return( LDAPTOOL_FILEURL_FILEIOERROR );
397 397 }
398 398
399 399 rlen = fread( bvp->bv_val, 1, bvp->bv_len, fp );
400 - eof = feof( fp );
401 400 fclose( fp );
402 401
403 402 if ( rlen != (long)bvp->bv_len ) {
404 403 if ( reporterrs ) perror( path );
405 404 free( bvp->bv_val );
406 405 return( LDAPTOOL_FILEURL_FILEIOERROR );
407 406 }
408 407
409 408 bvp->bv_val[ bvp->bv_len ] = '\0';
410 409 return( LDAPTOOL_FILEURL_SUCCESS );
411 410 }
412 411
413 412
414 413 /*
415 414 * Return a non-zero value if the string s begins with prefix and zero if not.
416 415 */
417 416 static int
418 417 str_starts_with( const char *s, char *prefix )
419 418 {
420 419 size_t prefix_len;
421 420
422 421 if ( s == NULL || prefix == NULL ) {
423 422 return( 0 );
424 423 }
425 424
426 425 prefix_len = strlen( prefix );
427 426 if ( strlen( s ) < prefix_len ) {
428 427 return( 0 );
429 428 }
430 429
431 430 return( strncmp( s, prefix, prefix_len ) == 0 );
432 431 }
433 432
434 433
435 434 /*
436 435 * Remove URL hex escapes from s... done in place. The basic concept for
437 436 * this routine is borrowed from the WWW library HTUnEscape() routine.
438 437 *
439 438 * A similar function called nsldapi_hex_unescape can be found in
440 439 * ../../libraries/libldap/unescape.c
441 440 */
442 441 static void
443 442 hex_unescape( char *s )
444 443 {
445 444 char *p;
446 445
447 446 for ( p = s; *s != '\0'; ++s ) {
448 447 if ( *s == '%' ) {
449 448 if ( *++s != '\0' ) {
450 449 *p = unhex( *s ) << 4;
451 450 }
452 451 if ( *++s != '\0' ) {
453 452 *p++ += unhex( *s );
454 453 }
455 454 } else {
456 455 *p++ = *s;
457 456 }
458 457 }
459 458
460 459 *p = '\0';
461 460 }
462 461
463 462
464 463 /*
465 464 * Return the integer equivalent of one hex digit (in c).
466 465 *
467 466 * A similar function can be found in ../../libraries/libldap/unescape.c
468 467 */
469 468 static int
470 469 unhex( char c )
471 470 {
472 471 return( c >= '0' && c <= '9' ? c - '0'
473 472 : c >= 'A' && c <= 'F' ? c - 'A' + 10
474 473 : c - 'a' + 10 );
475 474 }
476 475
477 476
478 477 #define HREF_CHAR_ACCEPTABLE( c ) (( c >= '-' && c <= '9' ) || \
479 478 ( c >= '@' && c <= 'Z' ) || \
480 479 ( c == '_' ) || \
481 480 ( c >= 'a' && c <= 'z' ))
482 481
483 482 /*
484 483 * Like strcat(), except if any URL-special characters are found in s2
485 484 * they are escaped using the %HH convention and backslash characters are
486 485 * converted to forward slashes on Windows.
487 486 *
488 487 * Maximum space needed in s1 is 3 * strlen( s2 ) + 1.
489 488 *
490 489 * A similar function that does not convert the slashes called
491 490 * strcat_escaped() can be found in ../../libraries/libldap/tmplout.c
492 491 */
493 492 static void
494 493 strcpy_escaped_and_convert( char *s1, char *s2 )
495 494 {
496 495 char *p, *q;
497 496 char *hexdig = "0123456789ABCDEF";
498 497
499 498 p = s1 + strlen( s1 );
500 499 for ( q = s2; *q != '\0'; ++q ) {
501 500 #ifdef _WINDOWS
502 501 if ( *q == '\\' ) {
503 502 *p++ = '/';
504 503 } else
505 504 #endif /* _WINDOWS */
506 505
507 506 if ( HREF_CHAR_ACCEPTABLE( *q )) {
508 507 *p++ = *q;
509 508 } else {
510 509 *p++ = '%';
511 510 *p++ = hexdig[ 0x0F & ((*(unsigned char*)q) >> 4) ];
512 511 *p++ = hexdig[ 0x0F & *q ];
513 512 }
514 513 }
515 514
516 515 *p = '\0';
517 516 }
↓ open down ↓ |
107 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX