Back to index

lightning-sunbird  0.9+nobinonly
srchpref.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 /*
00038  * Copyright (c) 1993, 1994 Regents of the University of Michigan.
00039  * All rights reserved.
00040  *
00041  * Redistribution and use in source and binary forms are permitted
00042  * provided that this notice is preserved and that due credit is given
00043  * to the University of Michigan at Ann Arbor. The name of the University
00044  * may not be used to endorse or promote products derived from this
00045  * software without specific prior written permission. This software
00046  * is provided ``as is'' without express or implied warranty.
00047  *
00048  */
00049 /*
00050  * searchpref.c:  search preferences library routines for LDAP clients
00051  */
00052 
00053 #include "ldap-int.h"
00054 #include "srchpref.h"
00055 
00056 int nsldapi_next_line_tokens( char **bufp, long *blenp, char ***toksp );
00057 void nsldapi_free_strarray( char **sap );
00058 static void free_searchobj( struct ldap_searchobj *so );
00059 static int read_next_searchobj( char **bufp, long *blenp,
00060        struct ldap_searchobj **sop, int soversion );
00061 
00062 
00063 static char          *sobjoptions[] = {
00064     "internal",
00065     NULL
00066 };
00067 
00068 
00069 static unsigned long sobjoptvals[] = {
00070     LDAP_SEARCHOBJ_OPT_INTERNAL,
00071 };
00072 
00073 
00074 int
00075 LDAP_CALL
00076 ldap_init_searchprefs( char *file, struct ldap_searchobj **solistp )
00077 {
00078     FILE      *fp;
00079     char      *buf;
00080     long      rlen, len;
00081     int              rc, eof;
00082 
00083     if (( fp = fopen( file, "r" )) == NULL ) {
00084        return( LDAP_SEARCHPREF_ERR_FILE );
00085     }
00086 
00087     if ( fseek( fp, 0L, SEEK_END ) != 0 ) {      /* move to end to get len */
00088        fclose( fp );
00089        return( LDAP_SEARCHPREF_ERR_FILE );
00090     }
00091 
00092     len = ftell( fp );
00093 
00094     if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {      /* back to start of file */
00095        fclose( fp );
00096        return( LDAP_SEARCHPREF_ERR_FILE );
00097     }
00098 
00099     if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
00100        fclose( fp );
00101        return( LDAP_SEARCHPREF_ERR_MEM );
00102     }
00103 
00104     rlen = fread( buf, 1, (size_t)len, fp );
00105     eof = feof( fp );
00106     fclose( fp );
00107 
00108     if ( rlen != len && !eof ) {   /* error:  didn't get the whole file */
00109        NSLDAPI_FREE( buf );
00110        return( LDAP_SEARCHPREF_ERR_FILE );
00111     }
00112 
00113     rc = ldap_init_searchprefs_buf( buf, rlen, solistp );
00114     NSLDAPI_FREE( buf );
00115 
00116     return( rc );
00117 }
00118 
00119 
00120 int
00121 LDAP_CALL
00122 ldap_init_searchprefs_buf( char *buf, long buflen,
00123        struct ldap_searchobj **solistp )
00124 {
00125     int                            rc = 0, version;
00126     char                    **toks;
00127     struct ldap_searchobj   *prevso, *so;
00128 
00129     *solistp = prevso = NULLSEARCHOBJ;
00130 
00131     if ( nsldapi_next_line_tokens( &buf, &buflen, &toks ) != 2 ||
00132            strcasecmp( toks[ 0 ], "version" ) != 0 ) {
00133        nsldapi_free_strarray( toks );
00134        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00135     }
00136     version = atoi( toks[ 1 ] );
00137     nsldapi_free_strarray( toks );
00138     if ( version != LDAP_SEARCHPREF_VERSION &&
00139            version != LDAP_SEARCHPREF_VERSION_ZERO ) {
00140        return( LDAP_SEARCHPREF_ERR_VERSION );
00141     }
00142 
00143     while ( buflen > 0 && ( rc = read_next_searchobj( &buf, &buflen, &so,
00144            version )) == 0 && so != NULLSEARCHOBJ ) {
00145        if ( prevso == NULLSEARCHOBJ ) {
00146            *solistp = so;
00147        } else {
00148            prevso->so_next = so;
00149        }
00150        prevso = so;
00151     }
00152 
00153     if ( rc != 0 ) {
00154        ldap_free_searchprefs( *solistp );
00155     }
00156 
00157     return( rc );
00158 }
00159            
00160 
00161 
00162 void
00163 LDAP_CALL
00164 ldap_free_searchprefs( struct ldap_searchobj *solist )
00165 {
00166     struct ldap_searchobj   *so, *nextso;
00167 
00168     if ( solist != NULL ) {
00169        for ( so = solist; so != NULL; so = nextso ) {
00170            nextso = so->so_next;
00171            free_searchobj( so );
00172        }
00173     }
00174     /* XXX XXX need to do some work here */
00175 }
00176 
00177 
00178 static void
00179 free_searchobj( struct ldap_searchobj *so )
00180 {
00181     if ( so != NULL ) {
00182        if ( so->so_objtypeprompt != NULL ) {
00183            NSLDAPI_FREE(  so->so_objtypeprompt );
00184        }
00185        if ( so->so_prompt != NULL ) {
00186            NSLDAPI_FREE(  so->so_prompt );
00187        }
00188        if ( so->so_filterprefix != NULL ) {
00189            NSLDAPI_FREE(  so->so_filterprefix );
00190        }
00191        if ( so->so_filtertag != NULL ) {
00192            NSLDAPI_FREE(  so->so_filtertag );
00193        }
00194        if ( so->so_defaultselectattr != NULL ) {
00195            NSLDAPI_FREE(  so->so_defaultselectattr );
00196        }
00197        if ( so->so_defaultselecttext != NULL ) {
00198            NSLDAPI_FREE(  so->so_defaultselecttext );
00199        }
00200        if ( so->so_salist != NULL ) {
00201            struct ldap_searchattr *sa, *nextsa;
00202            for ( sa = so->so_salist; sa != NULL; sa = nextsa ) {
00203               nextsa = sa->sa_next;
00204               if ( sa->sa_attrlabel != NULL ) {
00205                   NSLDAPI_FREE( sa->sa_attrlabel );
00206               }
00207               if ( sa->sa_attr != NULL ) {
00208                   NSLDAPI_FREE( sa->sa_attr );
00209               }
00210               if ( sa->sa_selectattr != NULL ) {
00211                   NSLDAPI_FREE( sa->sa_selectattr );
00212               }
00213               if ( sa->sa_selecttext != NULL ) {
00214                   NSLDAPI_FREE( sa->sa_selecttext );
00215               }
00216               NSLDAPI_FREE( sa );
00217            }
00218        }
00219        if ( so->so_smlist != NULL ) {
00220            struct ldap_searchmatch *sm, *nextsm;
00221            for ( sm = so->so_smlist; sm != NULL; sm = nextsm ) {
00222               nextsm = sm->sm_next;
00223               if ( sm->sm_matchprompt != NULL ) {
00224                   NSLDAPI_FREE( sm->sm_matchprompt );
00225               }
00226               if ( sm->sm_filter != NULL ) {
00227                   NSLDAPI_FREE( sm->sm_filter );
00228               }
00229               NSLDAPI_FREE( sm );
00230            }
00231        }
00232        NSLDAPI_FREE( so );
00233     }
00234 }
00235 
00236 
00237 
00238 struct ldap_searchobj *
00239 LDAP_CALL
00240 ldap_first_searchobj( struct ldap_searchobj *solist )
00241 {
00242     return( solist );
00243 }
00244 
00245 
00246 struct ldap_searchobj *
00247 LDAP_CALL
00248 ldap_next_searchobj( struct ldap_searchobj *solist, struct ldap_searchobj *so )
00249 {
00250     return( so == NULLSEARCHOBJ ? so : so->so_next );
00251 }
00252 
00253 
00254 
00255 static int
00256 read_next_searchobj( char **bufp, long *blenp, struct ldap_searchobj **sop,
00257        int soversion )
00258 {
00259     int                            i, j, tokcnt;
00260     char                    **toks;
00261     struct ldap_searchobj   *so;
00262     struct ldap_searchattr  **sa;
00263     struct ldap_searchmatch **sm;
00264 
00265     *sop = NULL;
00266 
00267     /*
00268      * Object type prompt comes first
00269      */
00270     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00271        nsldapi_free_strarray( toks );
00272        return( tokcnt == 0 ? 0 : LDAP_SEARCHPREF_ERR_SYNTAX );
00273     }
00274 
00275     if (( so = (struct ldap_searchobj *)NSLDAPI_CALLOC( 1,
00276            sizeof( struct ldap_searchobj ))) == NULL ) {
00277        nsldapi_free_strarray( toks );
00278        return(  LDAP_SEARCHPREF_ERR_MEM );
00279     }
00280     so->so_objtypeprompt = toks[ 0 ];
00281     NSLDAPI_FREE( (char *)toks );
00282 
00283     /*
00284      * if this is post-version zero, options come next
00285      */
00286     if ( soversion > LDAP_SEARCHPREF_VERSION_ZERO ) {
00287        if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) < 1 ) {
00288            nsldapi_free_strarray( toks );
00289            ldap_free_searchprefs( so );
00290            return( LDAP_SEARCHPREF_ERR_SYNTAX );
00291        }
00292        for ( i = 0; toks[ i ] != NULL; ++i ) {
00293            for ( j = 0; sobjoptions[ j ] != NULL; ++j ) {
00294               if ( strcasecmp( toks[ i ], sobjoptions[ j ] ) == 0 ) {
00295                   so->so_options |= sobjoptvals[ j ];
00296               }
00297            }
00298        }
00299        nsldapi_free_strarray( toks );
00300     }
00301 
00302     /*
00303      * "Fewer choices" prompt is next
00304      */
00305     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00306        nsldapi_free_strarray( toks );
00307        ldap_free_searchprefs( so );
00308        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00309     }
00310     so->so_prompt = toks[ 0 ];
00311     NSLDAPI_FREE( (char *)toks );
00312 
00313     /*
00314      * Filter prefix for "More Choices" searching is next
00315      */
00316     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00317        nsldapi_free_strarray( toks );
00318        ldap_free_searchprefs( so );
00319        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00320     }
00321     so->so_filterprefix = toks[ 0 ];
00322     NSLDAPI_FREE( (char *)toks );
00323 
00324     /*
00325      * "Fewer Choices" filter tag comes next
00326      */
00327     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00328        nsldapi_free_strarray( toks );
00329        ldap_free_searchprefs( so );
00330        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00331     }
00332     so->so_filtertag = toks[ 0 ];
00333     NSLDAPI_FREE( (char *)toks );
00334 
00335     /*
00336      * Selection (disambiguation) attribute comes next
00337      */
00338     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00339        nsldapi_free_strarray( toks );
00340        ldap_free_searchprefs( so );
00341        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00342     }
00343     so->so_defaultselectattr = toks[ 0 ];
00344     NSLDAPI_FREE( (char *)toks );
00345 
00346     /*
00347      * Label for selection (disambiguation) attribute
00348      */
00349     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00350        nsldapi_free_strarray( toks );
00351        ldap_free_searchprefs( so );
00352        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00353     }
00354     so->so_defaultselecttext = toks[ 0 ];
00355     NSLDAPI_FREE( (char *)toks );
00356 
00357     /*
00358      * Search scope is next
00359      */
00360     if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
00361        nsldapi_free_strarray( toks );
00362        ldap_free_searchprefs( so );
00363        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00364     }
00365     if ( !strcasecmp(toks[ 0 ], "subtree" )) {
00366        so->so_defaultscope = LDAP_SCOPE_SUBTREE;
00367     } else if ( !strcasecmp(toks[ 0 ], "onelevel" )) {
00368        so->so_defaultscope = LDAP_SCOPE_ONELEVEL;
00369     } else if ( !strcasecmp(toks[ 0 ], "base" )) {
00370        so->so_defaultscope = LDAP_SCOPE_BASE;
00371     } else {
00372        ldap_free_searchprefs( so );
00373        return( LDAP_SEARCHPREF_ERR_SYNTAX );
00374     }
00375     nsldapi_free_strarray( toks );
00376 
00377 
00378     /*
00379      * "More Choices" search option list comes next
00380      */
00381     sa = &( so->so_salist );
00382     while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
00383        if ( tokcnt < 5 ) {
00384            nsldapi_free_strarray( toks );
00385            ldap_free_searchprefs( so );
00386            return( LDAP_SEARCHPREF_ERR_SYNTAX );
00387        }
00388        if (( *sa = ( struct ldap_searchattr * )NSLDAPI_CALLOC( 1,
00389               sizeof( struct ldap_searchattr ))) == NULL ) {
00390            nsldapi_free_strarray( toks );
00391            ldap_free_searchprefs( so );
00392            return(  LDAP_SEARCHPREF_ERR_MEM );
00393        }
00394        ( *sa )->sa_attrlabel = toks[ 0 ];
00395        ( *sa )->sa_attr = toks[ 1 ];
00396        ( *sa )->sa_selectattr = toks[ 3 ];
00397        ( *sa )->sa_selecttext = toks[ 4 ];
00398        /* Deal with bitmap */
00399        ( *sa )->sa_matchtypebitmap = 0;
00400        for ( i = strlen( toks[ 2 ] ) - 1, j = 0; i >= 0; i--, j++ ) {
00401            if ( toks[ 2 ][ i ] == '1' ) {
00402               ( *sa )->sa_matchtypebitmap |= (1 << j);
00403            }
00404        }
00405        NSLDAPI_FREE( toks[ 2 ] );
00406        NSLDAPI_FREE( ( char * ) toks );
00407        sa = &(( *sa )->sa_next);
00408     }
00409     *sa = NULL;
00410 
00411     /*
00412      * Match types are last
00413      */
00414     sm = &( so->so_smlist );
00415     while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
00416        if ( tokcnt < 2 ) {
00417            nsldapi_free_strarray( toks );
00418            ldap_free_searchprefs( so );
00419            return( LDAP_SEARCHPREF_ERR_SYNTAX );
00420        }
00421        if (( *sm = ( struct ldap_searchmatch * )NSLDAPI_CALLOC( 1,
00422               sizeof( struct ldap_searchmatch ))) == NULL ) {
00423            nsldapi_free_strarray( toks );
00424            ldap_free_searchprefs( so );
00425            return(  LDAP_SEARCHPREF_ERR_MEM );
00426        }
00427        ( *sm )->sm_matchprompt = toks[ 0 ];
00428        ( *sm )->sm_filter = toks[ 1 ];
00429        NSLDAPI_FREE( ( char * ) toks );
00430        sm = &(( *sm )->sm_next );
00431     }
00432     *sm = NULL;
00433 
00434     *sop = so;
00435     return( 0 );
00436 }