2 * load the sasl plugins
3 * $Id: mac_dyn_dlopen.c,v 1.3 2003/02/13 19:55:59 rjs3 Exp $
6 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. The name "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any other legal
23 * details, please contact
24 * Office of Technology Transfer
25 * Carnegie Mellon University
27 * Pittsburgh, PA 15213-3890
28 * (412) 268-4387, fax: (412) 268-7395
29 * tech-transfer@andrew.cmu.edu
31 * 4. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by Computing Services
34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52 #include <CodeFragments.h>
54 #include <Resources.h>
59 #include <FSpCompat.h>
63 * The following data structure defines the structure of a code fragment
64 * resource. We can cast the resource to be of this type to access
65 * any fields we need to see.
76 char arrayStart; /* Array of externalItems begins here. */
78 typedef struct CfrgHeader CfrgHeader, *CfrgHeaderPtr, **CfrgHeaderPtrHand;
81 * The below structure defines a cfrag item within the cfrag resource.
97 Str255 name; /* This is actually variable sized. */
99 typedef struct CfrgItem CfrgItem;
108 #if TARGET_API_MAC_CARBON
109 #define SASL_PLUGIN_DIR "\p:sasl v2:carbon:biff"
111 #define SASL_PLUGIN_DIR "\p:sasl v2:biff"
114 typedef struct lib_list
116 struct lib_list *next;
120 static lib_list_t *lib_list_head = NULL;
123 * add the passed extension
125 int _macsasl_get_fsspec(FSSpec *fspec,
129 CFragConnectionID connID;
131 unsigned long offset = 0;
132 unsigned long length = kCFragGoesToEOF;
133 unsigned char package_name[255];
137 newhead = sasl_ALLOC(sizeof(lib_list_t));
138 if(!newhead) return SASL_NOMEM;
141 rc=GetDiskFragment(fspec,offset,length,package_name,
142 kLoadCFrag,&connID,&dummy,error_text);
148 newhead->library = (void *)connID;
149 newhead->next = lib_list_head;
150 lib_list_head = newhead;
152 *libraryptr = (void *)connID;
156 int _sasl_locate_entry(void *library, const char *entryname,
160 #if TARGET_API_MAC_CARBON
164 CFragSymbolClass symClass;
168 return SASL_BADPARAM;
172 return SASL_BADPARAM;
176 return SASL_BADPARAM;
179 #if TARGET_API_MAC_CARBON
180 strcpy(cstr,entryname);
181 CopyCStringToPascal(cstr, pentry);
183 strcpy(pentry,entryname);
187 rc = FindSymbol((CFragConnectionID)library,pentry,entry_point, &symClass);
188 if ((rc!=noErr) || (symClass==kDataCFragSymbol))
194 static int _sasl_plugin_load(char *plugin, void *library,
195 const char *entryname,
196 int (*add_plugin)(const char *, void *))
201 result = _sasl_locate_entry(library, entryname, &entry_point);
202 if(result == SASL_OK) {
203 result = add_plugin(plugin, entry_point);
204 // if(result != SASL_OK)
205 // _sasl_log(NULL, SASL_LOG_ERR,
206 // "_sasl_plugin_load failed on %s for plugin: %s\n",
207 // entryname, plugin);
214 * does the passed string a occur and the end of string b?
216 int _macsasl_ends_in(char *a, char *b)
222 return (memcmp(a,b+(blen-alen),alen)==0);
226 * scan the passed directory loading sasl extensions
228 int _macsasl_find_extensions_in_dir(short vref,long dir_id,
229 const add_plugin_list_t *entrypoints)
232 unsigned char aname[300];
238 const add_plugin_list_t *cur_ep;
242 memset(&cinfo,0,sizeof(cinfo));
244 cinfo.hFileInfo.ioVRefNum=vref;
245 cinfo.hFileInfo.ioNamePtr=aname;
246 cinfo.hFileInfo.ioFDirIndex=findex++;
247 cinfo.hFileInfo.ioDirID=dir_id;
248 os=PBGetCatInfo(&cinfo,FALSE);
251 aname[aname[0]+1] = 0;
253 /* skip over non shlb files */
254 if(!_macsasl_ends_in(".shlb",aname+1))
256 os=FSMakeFSSpec(vref,dir_id,aname,&a_plugin);
260 /* skip "lib" and cut off suffix --
261 this only need be approximate */
262 strcpy(plugname, aname + 1);
263 c = strchr(plugname, (int)'.');
266 if (!_macsasl_get_fsspec(&a_plugin,&library))
267 for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
268 _sasl_plugin_load(plugname, library, cur_ep->entryname,
270 /* If this fails, it's not the end of the world */
276 /* gets the list of mechanisms */
277 int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
278 const sasl_callback_t *getpath_cb,
279 const sasl_callback_t *verifyfile_cb)
282 short extensions_vref;
283 long extensions_dirid;
285 /* find the extensions folder */
286 rc=FindFolder(kOnSystemDisk,kExtensionFolderType,FALSE,
287 &extensions_vref,&extensions_dirid);
289 return SASL_BADPARAM;
290 rc=FSMakeFSSpec(extensions_vref,extensions_dirid,SASL_PLUGIN_DIR,&sasl_dir);
292 * if a plugin named biff exits or not we really dont care
293 * if it does get rc 0 if it does not get -43 (fnfErr)
294 * if the sasl dir doesnt exist we get -120 (dirNFFErr)
296 if((rc!=0)&&(rc!=fnfErr))
297 return SASL_BADPARAM;
299 * now extensions_vref is volume
300 * sasl_dir.parID is dirid for sasl plugins folder
303 return _macsasl_find_extensions_in_dir(extensions_vref,sasl_dir.parID,entrypoints);
307 _sasl_done_with_plugins(void)
309 lib_list_t *libptr, *libptr_next;
311 for(libptr = lib_list_head; libptr; libptr = libptr_next) {
312 libptr_next = libptr->next;
314 CloseConnection((CFragConnectionID*)&libptr->library);
318 lib_list_head = NULL;