Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
fileurl.c File Reference
#include "ldaptool.h"
#include "fileurl.h"
#include <ctype.h>

Go to the source code of this file.

Defines

#define HREF_CHAR_ACCEPTABLE(c)

Functions

static int str_starts_with (const char *s, char *prefix)
static void hex_unescape (char *s)
static int unhex (char c)
static void strcpy_escaped_and_convert (char *s1, char *s2)
static int berval_from_file (const char *path, struct berval *bvp, int reporterrs)
int ldaptool_fileurl2path (const char *fileurl, char **localpathp)
int ldaptool_path2fileurl (char *path, char **urlp)
int ldaptool_berval_from_ldif_value (const char *value, int vlen, struct berval *bvp, int recognize_url_syntax, int always_try_file, int reporterrs)
int ldaptool_fileurlerr2ldaperr (int lderr)

Define Documentation

Value:
(( c >= '-' && c <= '9' ) ||       \
                                    ( c >= '@' && c <= 'Z' ) ||       \
                                    ( c == '_' ) ||            \
                                    ( c >= 'a' && c <= 'z' ))

Definition at line 467 of file fileurl.c.


Function Documentation

static int berval_from_file ( const char *  path,
struct berval bvp,
int  reporterrs 
) [static]

Definition at line 352 of file fileurl.c.

{
    FILE      *fp;
    long      rlen;
    int              eof;
#if defined( XP_WIN32 )
    char      mode[20] = "r+b";
#else
    char      mode[20] = "r";
#endif

    if (( fp = fopen( path, mode )) == NULL ) {
       if ( reporterrs ) perror( path );
       return( LDAPTOOL_FILEURL_FILEIOERROR );
    }

    if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
       if ( reporterrs ) perror( path );
       fclose( fp );
       return( LDAPTOOL_FILEURL_FILEIOERROR );
    }

    bvp->bv_len = ftell( fp );

    if (( bvp->bv_val = (char *)malloc( bvp->bv_len + 1 )) == NULL ) {
       if ( reporterrs ) perror( "malloc" );
       fclose( fp );
       return( LDAPTOOL_FILEURL_NOMEMORY );
    }

    if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {
       if ( reporterrs ) perror( path );
       fclose( fp );
       return( LDAPTOOL_FILEURL_FILEIOERROR );
    }

    rlen = fread( bvp->bv_val, 1, bvp->bv_len, fp );
    eof = feof( fp );
    fclose( fp );

    if ( rlen != (long)bvp->bv_len ) {
       if ( reporterrs ) perror( path );
       free( bvp->bv_val );
       return( LDAPTOOL_FILEURL_FILEIOERROR );
    }

    bvp->bv_val[ bvp->bv_len ] = '\0';
    return( LDAPTOOL_FILEURL_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hex_unescape ( char *  s) [static]

Definition at line 432 of file fileurl.c.

{
       char   *p;

       for ( p = s; *s != '\0'; ++s ) {
              if ( *s == '%' ) {
                     if ( *++s != '\0' ) {
                            *p = unhex( *s ) << 4;
                     }
                     if ( *++s != '\0' ) {
                            *p++ += unhex( *s );
                     }
              } else {
                     *p++ = *s;
              }
       }

       *p = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldaptool_berval_from_ldif_value ( const char *  value,
int  vlen,
struct berval bvp,
int  recognize_url_syntax,
int  always_try_file,
int  reporterrs 
)

Definition at line 233 of file fileurl.c.

{
    int       rc = LDAPTOOL_FILEURL_SUCCESS;     /* optimistic */
    struct stat      fstats;

    /* recognize "attr :< url" syntax if LDIF version is >= 1 */

    if ( recognize_url_syntax && *value == '<' ) {
        const char   *url;
        char         *path;

       for ( url = value + 1; isspace( *url ); ++url ) {
           ;  /* NULL */
       }

       if (strlen(url) > 7 && strncasecmp(url, "file://", 7) == 0) {
         /*
          * We only support file:// URLs for now.
          */
         rc = ldaptool_fileurl2path( url, &path );
         switch( rc ) {
         case LDAPTOOL_FILEURL_NOTAFILEURL:
             if ( reporterrs ) fprintf( stderr, "%s: unsupported URL \"%s\";"
                " use a file:// URL instead.\n", ldaptool_progname, url );
             break;

         case LDAPTOOL_FILEURL_MISSINGPATH:
             if ( reporterrs ) fprintf( stderr,
                  "%s: unable to process URL \"%s\" --"
                  " missing path.\n", ldaptool_progname, url );
             break;

         case LDAPTOOL_FILEURL_NONLOCAL:
             if ( reporterrs ) fprintf( stderr,
                  "%s: unable to process URL \"%s\" -- only"
                  " local file:// URLs are supported.\n",
                  ldaptool_progname, url );
             break;

         case LDAPTOOL_FILEURL_NOMEMORY:
             if ( reporterrs ) perror( "ldaptool_fileurl2path" );
             break;

         case LDAPTOOL_FILEURL_SUCCESS:
             if ( stat( path, &fstats ) != 0 ) {
                if ( reporterrs ) perror( path );
             } else if ( fstats.st_mode & S_IFDIR ) {   
                if ( reporterrs ) fprintf( stderr,
                     "%s: %s is a directory, not a file\n",
                     ldaptool_progname, path );
                rc = LDAPTOOL_FILEURL_FILEIOERROR;
             } else {
                rc = berval_from_file( path, bvp, reporterrs );
             }
             free( path );
             break;

         default:
             if ( reporterrs ) fprintf( stderr,
                  "%s: unable to process URL \"%s\""
                  " -- unknown error\n", ldaptool_progname, url );
         }
       }
    }
    if ( always_try_file && (stat( value, &fstats ) == 0) &&
            !(fstats.st_mode & S_IFDIR)) {       /* get value from file */
       rc = berval_from_file( value, bvp, reporterrs );
    } else {
       bvp->bv_len = vlen;
       if (( bvp->bv_val = (char *)malloc( vlen + 1 )) == NULL ) {
           if ( reporterrs ) perror( "malloc" );
           rc = LDAPTOOL_FILEURL_NOMEMORY;
       } else {
           SAFEMEMCPY( bvp->bv_val, value, vlen );
           bvp->bv_val[ vlen ] = '\0';
       }
    }

    return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ldaptool_fileurl2path ( const char *  fileurl,
char **  localpathp 
)

Definition at line 78 of file fileurl.c.

{
    const char       *path;
    char      *pathcopy;

    /*
     * Make sure this is a file URL we can handle.
     */
    if ( !str_starts_with( fileurl, "file:" )) {
       return( LDAPTOOL_FILEURL_NOTAFILEURL );
    }

    path = fileurl + 5;            /* skip past "file:" scheme prefix */

    if ( *path != '/' ) {
       return( LDAPTOOL_FILEURL_MISSINGPATH );
    }

    ++path;                 /* skip past '/' at end of "file:/" */

    if ( *path == '/' ) {
       ++path;                     /* remainder is now host/path or /path */
       if ( *path != '/' ) {
           /*
            * Make sure it is for the local host.
            */
           if ( str_starts_with( path, "localhost/" )) {
              path += 9;
           } else {
              return( LDAPTOOL_FILEURL_NONLOCAL );
           }
       }
    } else {         /* URL is of the form file:/path */
       --path;
    }

    /*
     * The remainder is now of the form /path.  On Windows, skip past the
     * leading slash if a drive letter is present.
     */
#ifdef _WINDOWS
    if ( isalpha( path[1] ) && ( path[2] == '|' || path[2] == ':' )) {
       ++path;
    }
#endif /* _WINDOWS */

    /*
     * Duplicate the path so we can safely alter it.
     * Unescape any %HH sequences.
     */
    if (( pathcopy = strdup( path )) == NULL ) {
       return( LDAPTOOL_FILEURL_NOMEMORY );
    }
    hex_unescape( pathcopy );

#ifdef _WINDOWS
    /*
     * Convert forward slashes to backslashes for Windows.  Also,
     * if we see a drive letter / vertical bar combination (e.g., c|)
     * at the beginning of the path, replace the '|' with a ':'.
     */
    {
       char   *p;

       for ( p = pathcopy; *p != '\0'; ++p ) {
           if ( *p == '/' ) {
              *p = '\\';
           }
       }
    }

    if ( isalpha( pathcopy[0] ) && pathcopy[1] == '|' ) {
       pathcopy[1] = ':';
    }
#endif /* _WINDOWS */

    *localpathp = pathcopy;
    return( LDAPTOOL_FILEURL_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 321 of file fileurl.c.

{
    int              rc;

    switch( lderr ) {
    case LDAPTOOL_FILEURL_SUCCESS:
       rc = LDAP_SUCCESS;
       break;
    case LDAPTOOL_FILEURL_NOMEMORY:
       rc = LDAP_NO_MEMORY;
       break;
    default:
       rc = LDAP_PARAM_ERROR;
    }

    return( rc );
} 

Here is the caller graph for this function:

int ldaptool_path2fileurl ( char *  path,
char **  urlp 
)

Definition at line 173 of file fileurl.c.

{
    char      *p, *url, *prefix ="file:";

    if ( NULL == path ) {
       path = "/";
    }

    /*
     * Allocate space for the URL, taking into account that path may
     * expand during the hex escaping process.
     */
    if (( url = malloc( strlen( prefix ) + 3 * strlen( path ) + 1 )) == NULL ) {
       return( LDAPTOOL_FILEURL_NOMEMORY );
    }

    strcpy( url, prefix );
    p = url + strlen( prefix );

#ifdef _WINDOWS
    /*
     * On Windows, convert leading drive letters (e.g., C:) to the correct URL
     * syntax (e.g., C|).
     */
    if ( isalpha( path[0] ) && path[1] == ':' ) {
       *p++ = path[0];
       *p++ = '|';
       path += 2;
       *p = '\0';
    }
#endif /* _WINDOWS */

    /*
     * Append the path, encoding any URL-special characters using the %HH
     * convention.
     * On Windows, convert backwards slashes in the path to forward ones.
     */
    strcpy_escaped_and_convert( p, path );

    *urlp = url;
    return( LDAPTOOL_FILEURL_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int str_starts_with ( const char *  s,
char *  prefix 
) [static]

Definition at line 407 of file fileurl.c.

{
    size_t    prefix_len;

    if ( s == NULL || prefix == NULL ) {
       return( 0 );
    }

    prefix_len = strlen( prefix );
    if ( strlen( s ) < prefix_len ) {
       return( 0 );
    }

    return( strncmp( s, prefix, prefix_len ) == 0 );
}

Here is the caller graph for this function:

static void strcpy_escaped_and_convert ( char *  s1,
char *  s2 
) [static]

Definition at line 483 of file fileurl.c.

{
    char      *p, *q;
    char      *hexdig = "0123456789ABCDEF";

    p = s1 + strlen( s1 );
    for ( q = s2; *q != '\0'; ++q ) {
#ifdef _WINDOWS
       if ( *q == '\\' ) {
                *p++ = '/';
       } else
#endif /* _WINDOWS */

       if ( HREF_CHAR_ACCEPTABLE( *q )) {
           *p++ = *q;
       } else {
           *p++ = '%';
           *p++ = hexdig[ 0x0F & ((*(unsigned char*)q) >> 4) ];
           *p++ = hexdig[ 0x0F & *q ];
       }
    }

    *p = '\0';
}

Here is the caller graph for this function:

static int unhex ( char  c) [static]

Definition at line 459 of file fileurl.c.

{
       return( c >= '0' && c <= '9' ? c - '0'
           : c >= 'A' && c <= 'F' ? c - 'A' + 10
           : c - 'a' + 10 );
}

Here is the caller graph for this function: