xref: /aosp_15_r20/external/libxml2/os400/dlfcn/dlfcn.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker ***     dlopen(), dlclose() dlsym(), dlerror() emulation for OS/400.
3*7c568831SAndroid Build Coastguard Worker ***
4*7c568831SAndroid Build Coastguard Worker ***     See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker ***
6*7c568831SAndroid Build Coastguard Worker ***     Author: Patrick Monnerat <[email protected]>, DATASPHERE S.A.
7*7c568831SAndroid Build Coastguard Worker **/
8*7c568831SAndroid Build Coastguard Worker 
9*7c568831SAndroid Build Coastguard Worker #include <stdarg.h>
10*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
11*7c568831SAndroid Build Coastguard Worker #include <ctype.h>
12*7c568831SAndroid Build Coastguard Worker #include <errno.h>
13*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
14*7c568831SAndroid Build Coastguard Worker #include <unistd.h>
15*7c568831SAndroid Build Coastguard Worker #include <string.h>
16*7c568831SAndroid Build Coastguard Worker #include <dirent.h>
17*7c568831SAndroid Build Coastguard Worker #include <pthread.h>
18*7c568831SAndroid Build Coastguard Worker 
19*7c568831SAndroid Build Coastguard Worker #include <sys/types.h>
20*7c568831SAndroid Build Coastguard Worker #include <sys/stat.h>
21*7c568831SAndroid Build Coastguard Worker 
22*7c568831SAndroid Build Coastguard Worker #include <except.h>             /* AS400 exceptions. */
23*7c568831SAndroid Build Coastguard Worker #include <miptrnam.h>           /* MI pointers support. */
24*7c568831SAndroid Build Coastguard Worker #include <qusec.h>              /* Error structures. */
25*7c568831SAndroid Build Coastguard Worker #include <qp0lstdi.h>           /* Path to QSYS object name. */
26*7c568831SAndroid Build Coastguard Worker #include <qp0z1170.h>           /* For Qp0zInitEnv(). */
27*7c568831SAndroid Build Coastguard Worker #include <qleawi.h>             /* For QleActBndPgmLong() definitions. */
28*7c568831SAndroid Build Coastguard Worker #include <qsy.h>                /* Qualified name structure. */
29*7c568831SAndroid Build Coastguard Worker #include <qmhrtvm.h>            /* Retrieve message from message file. */
30*7c568831SAndroid Build Coastguard Worker 
31*7c568831SAndroid Build Coastguard Worker #include <mih/rinzstat.h>
32*7c568831SAndroid Build Coastguard Worker #include <mih/matactex.h>
33*7c568831SAndroid Build Coastguard Worker 
34*7c568831SAndroid Build Coastguard Worker #include "libxml/hash.h"
35*7c568831SAndroid Build Coastguard Worker #include "dlfcn.h"
36*7c568831SAndroid Build Coastguard Worker 
37*7c568831SAndroid Build Coastguard Worker 
38*7c568831SAndroid Build Coastguard Worker /**
39*7c568831SAndroid Build Coastguard Worker ***     Maximum internal path length.
40*7c568831SAndroid Build Coastguard Worker **/
41*7c568831SAndroid Build Coastguard Worker 
42*7c568831SAndroid Build Coastguard Worker #define MAXPATHLEN              5120
43*7c568831SAndroid Build Coastguard Worker 
44*7c568831SAndroid Build Coastguard Worker 
45*7c568831SAndroid Build Coastguard Worker /**
46*7c568831SAndroid Build Coastguard Worker ***     Maximum error string length.
47*7c568831SAndroid Build Coastguard Worker **/
48*7c568831SAndroid Build Coastguard Worker 
49*7c568831SAndroid Build Coastguard Worker #define MAX_ERR_STR             511
50*7c568831SAndroid Build Coastguard Worker 
51*7c568831SAndroid Build Coastguard Worker 
52*7c568831SAndroid Build Coastguard Worker /**
53*7c568831SAndroid Build Coastguard Worker ***     Field address macro.
54*7c568831SAndroid Build Coastguard Worker **/
55*7c568831SAndroid Build Coastguard Worker 
56*7c568831SAndroid Build Coastguard Worker #define offset_by(t, b, o)      ((t *) ((char *) (b) + (unsigned int) (o)))
57*7c568831SAndroid Build Coastguard Worker 
58*7c568831SAndroid Build Coastguard Worker 
59*7c568831SAndroid Build Coastguard Worker /**
60*7c568831SAndroid Build Coastguard Worker ***     Global flags.
61*7c568831SAndroid Build Coastguard Worker **/
62*7c568831SAndroid Build Coastguard Worker 
63*7c568831SAndroid Build Coastguard Worker #define INITED          000001          /* Package has been initialized. */
64*7c568831SAndroid Build Coastguard Worker #define THREADS         000002          /* Multithreaded job. */
65*7c568831SAndroid Build Coastguard Worker #define MULTIBUF        000004          /* One error buffer per thread. */
66*7c568831SAndroid Build Coastguard Worker 
67*7c568831SAndroid Build Coastguard Worker 
68*7c568831SAndroid Build Coastguard Worker /**
69*7c568831SAndroid Build Coastguard Worker ***     DLL handle private structure.
70*7c568831SAndroid Build Coastguard Worker **/
71*7c568831SAndroid Build Coastguard Worker 
72*7c568831SAndroid Build Coastguard Worker typedef struct {
73*7c568831SAndroid Build Coastguard Worker         Qle_ABP_Info_Long_t     actinfo;        /* Activation information. */
74*7c568831SAndroid Build Coastguard Worker         _SYSPTR                 pointer;        /* Pointer to DLL object. */
75*7c568831SAndroid Build Coastguard Worker         unsigned int            actcount;       /* Activation count. */
76*7c568831SAndroid Build Coastguard Worker }               dlinfo;
77*7c568831SAndroid Build Coastguard Worker 
78*7c568831SAndroid Build Coastguard Worker 
79*7c568831SAndroid Build Coastguard Worker /**
80*7c568831SAndroid Build Coastguard Worker ***     Per-thread structure.
81*7c568831SAndroid Build Coastguard Worker **/
82*7c568831SAndroid Build Coastguard Worker 
83*7c568831SAndroid Build Coastguard Worker typedef struct {
84*7c568831SAndroid Build Coastguard Worker         unsigned int    lockcount;              /* Mutex lock count. */
85*7c568831SAndroid Build Coastguard Worker         unsigned int    iserror;                /* Flag error present. */
86*7c568831SAndroid Build Coastguard Worker         char            str[MAX_ERR_STR + 1];   /* Error string buffer. */
87*7c568831SAndroid Build Coastguard Worker }               dlts_t;
88*7c568831SAndroid Build Coastguard Worker 
89*7c568831SAndroid Build Coastguard Worker 
90*7c568831SAndroid Build Coastguard Worker static pthread_mutex_t  dlmutex = PTHREAD_MUTEX_INITIALIZER;
91*7c568831SAndroid Build Coastguard Worker static xmlHashTablePtr  dldir = (xmlHashTablePtr) NULL; /* DLL directory. */
92*7c568831SAndroid Build Coastguard Worker static unsigned int     dlflags = 0;                    /* Package flags. */
93*7c568831SAndroid Build Coastguard Worker static pthread_key_t    dlkey;
94*7c568831SAndroid Build Coastguard Worker static dlts_t           static_buf;             /* Static error buffer. */
95*7c568831SAndroid Build Coastguard Worker 
96*7c568831SAndroid Build Coastguard Worker 
97*7c568831SAndroid Build Coastguard Worker 
98*7c568831SAndroid Build Coastguard Worker static void
dlthreadterm(void * mem)99*7c568831SAndroid Build Coastguard Worker dlthreadterm(void * mem)
100*7c568831SAndroid Build Coastguard Worker 
101*7c568831SAndroid Build Coastguard Worker {
102*7c568831SAndroid Build Coastguard Worker         free(mem);
103*7c568831SAndroid Build Coastguard Worker         pthread_setspecific(dlkey, NULL);
104*7c568831SAndroid Build Coastguard Worker }
105*7c568831SAndroid Build Coastguard Worker 
106*7c568831SAndroid Build Coastguard Worker 
107*7c568831SAndroid Build Coastguard Worker static void
dlterm(void)108*7c568831SAndroid Build Coastguard Worker dlterm(void)
109*7c568831SAndroid Build Coastguard Worker 
110*7c568831SAndroid Build Coastguard Worker {
111*7c568831SAndroid Build Coastguard Worker         void * p;
112*7c568831SAndroid Build Coastguard Worker 
113*7c568831SAndroid Build Coastguard Worker         if (dlflags & MULTIBUF) {
114*7c568831SAndroid Build Coastguard Worker                 p = pthread_getspecific(dlkey);
115*7c568831SAndroid Build Coastguard Worker 
116*7c568831SAndroid Build Coastguard Worker                 if (p)
117*7c568831SAndroid Build Coastguard Worker                         dlthreadterm(p);
118*7c568831SAndroid Build Coastguard Worker                 }
119*7c568831SAndroid Build Coastguard Worker 
120*7c568831SAndroid Build Coastguard Worker         if (dlflags & THREADS)
121*7c568831SAndroid Build Coastguard Worker                 pthread_mutex_lock(&dlmutex);
122*7c568831SAndroid Build Coastguard Worker 
123*7c568831SAndroid Build Coastguard Worker         if (dldir) {
124*7c568831SAndroid Build Coastguard Worker                 xmlHashFree(dldir, (xmlHashDeallocator) NULL);
125*7c568831SAndroid Build Coastguard Worker                 dldir = NULL;
126*7c568831SAndroid Build Coastguard Worker                 }
127*7c568831SAndroid Build Coastguard Worker 
128*7c568831SAndroid Build Coastguard Worker         if (dlflags & MULTIBUF)
129*7c568831SAndroid Build Coastguard Worker                 pthread_key_delete(dlkey);
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker         dlflags |= ~(INITED | MULTIBUF);
132*7c568831SAndroid Build Coastguard Worker         pthread_mutex_unlock(&dlmutex);
133*7c568831SAndroid Build Coastguard Worker         pthread_mutex_destroy(&dlmutex);
134*7c568831SAndroid Build Coastguard Worker }
135*7c568831SAndroid Build Coastguard Worker 
136*7c568831SAndroid Build Coastguard Worker 
137*7c568831SAndroid Build Coastguard Worker static void
dlinit(void)138*7c568831SAndroid Build Coastguard Worker dlinit(void)
139*7c568831SAndroid Build Coastguard Worker 
140*7c568831SAndroid Build Coastguard Worker {
141*7c568831SAndroid Build Coastguard Worker         int locked;
142*7c568831SAndroid Build Coastguard Worker 
143*7c568831SAndroid Build Coastguard Worker         /**
144*7c568831SAndroid Build Coastguard Worker         ***     Initialize the package.
145*7c568831SAndroid Build Coastguard Worker         ***     Should be call once per process.
146*7c568831SAndroid Build Coastguard Worker         **/
147*7c568831SAndroid Build Coastguard Worker 
148*7c568831SAndroid Build Coastguard Worker         locked = !pthread_mutex_lock(&dlmutex);
149*7c568831SAndroid Build Coastguard Worker 
150*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & INITED)) {
151*7c568831SAndroid Build Coastguard Worker                 dlflags &= ~THREADS;
152*7c568831SAndroid Build Coastguard Worker 
153*7c568831SAndroid Build Coastguard Worker                 if (locked)
154*7c568831SAndroid Build Coastguard Worker                         dlflags |= THREADS;
155*7c568831SAndroid Build Coastguard Worker 
156*7c568831SAndroid Build Coastguard Worker                 Qp0zInitEnv();
157*7c568831SAndroid Build Coastguard Worker                 dldir = xmlHashCreate(16);
158*7c568831SAndroid Build Coastguard Worker                 dlflags &= ~MULTIBUF;
159*7c568831SAndroid Build Coastguard Worker 
160*7c568831SAndroid Build Coastguard Worker                 if (dlflags & THREADS)
161*7c568831SAndroid Build Coastguard Worker                         if (!pthread_key_create(&dlkey, dlthreadterm))
162*7c568831SAndroid Build Coastguard Worker                                 dlflags |= MULTIBUF;
163*7c568831SAndroid Build Coastguard Worker 
164*7c568831SAndroid Build Coastguard Worker                 atexit(dlterm);
165*7c568831SAndroid Build Coastguard Worker                 dlflags |= INITED;
166*7c568831SAndroid Build Coastguard Worker                 }
167*7c568831SAndroid Build Coastguard Worker 
168*7c568831SAndroid Build Coastguard Worker         if (locked)
169*7c568831SAndroid Build Coastguard Worker                 pthread_mutex_unlock(&dlmutex);
170*7c568831SAndroid Build Coastguard Worker }
171*7c568831SAndroid Build Coastguard Worker 
172*7c568831SAndroid Build Coastguard Worker 
173*7c568831SAndroid Build Coastguard Worker static void
dlthreadinit(void)174*7c568831SAndroid Build Coastguard Worker dlthreadinit(void)
175*7c568831SAndroid Build Coastguard Worker 
176*7c568831SAndroid Build Coastguard Worker {
177*7c568831SAndroid Build Coastguard Worker         dlts_t * p;
178*7c568831SAndroid Build Coastguard Worker 
179*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & INITED))
180*7c568831SAndroid Build Coastguard Worker                 dlinit();
181*7c568831SAndroid Build Coastguard Worker 
182*7c568831SAndroid Build Coastguard Worker         if (dlflags & MULTIBUF) {
183*7c568831SAndroid Build Coastguard Worker                 p = pthread_getspecific(dlkey);
184*7c568831SAndroid Build Coastguard Worker 
185*7c568831SAndroid Build Coastguard Worker                 if (!p) {
186*7c568831SAndroid Build Coastguard Worker                         p = (dlts_t *) malloc(sizeof *p);
187*7c568831SAndroid Build Coastguard Worker 
188*7c568831SAndroid Build Coastguard Worker                         if (p) {
189*7c568831SAndroid Build Coastguard Worker                                 p->lockcount = 0;
190*7c568831SAndroid Build Coastguard Worker                                 p->iserror = 0;
191*7c568831SAndroid Build Coastguard Worker 
192*7c568831SAndroid Build Coastguard Worker                                 if (pthread_setspecific(dlkey, p))
193*7c568831SAndroid Build Coastguard Worker                                         free(p);
194*7c568831SAndroid Build Coastguard Worker                                 }
195*7c568831SAndroid Build Coastguard Worker                         }
196*7c568831SAndroid Build Coastguard Worker                 }
197*7c568831SAndroid Build Coastguard Worker }
198*7c568831SAndroid Build Coastguard Worker 
199*7c568831SAndroid Build Coastguard Worker 
200*7c568831SAndroid Build Coastguard Worker static void
dllock(void)201*7c568831SAndroid Build Coastguard Worker dllock(void)
202*7c568831SAndroid Build Coastguard Worker 
203*7c568831SAndroid Build Coastguard Worker {
204*7c568831SAndroid Build Coastguard Worker         dlts_t * p;
205*7c568831SAndroid Build Coastguard Worker 
206*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & THREADS))
207*7c568831SAndroid Build Coastguard Worker                 return;
208*7c568831SAndroid Build Coastguard Worker 
209*7c568831SAndroid Build Coastguard Worker         if (dlflags & MULTIBUF) {
210*7c568831SAndroid Build Coastguard Worker                 p = pthread_getspecific(dlkey);
211*7c568831SAndroid Build Coastguard Worker 
212*7c568831SAndroid Build Coastguard Worker                 if (p && p->lockcount) {
213*7c568831SAndroid Build Coastguard Worker                         p->lockcount++;
214*7c568831SAndroid Build Coastguard Worker                         return;
215*7c568831SAndroid Build Coastguard Worker                         }
216*7c568831SAndroid Build Coastguard Worker                 }
217*7c568831SAndroid Build Coastguard Worker         else
218*7c568831SAndroid Build Coastguard Worker                 p = (dlts_t *) NULL;
219*7c568831SAndroid Build Coastguard Worker 
220*7c568831SAndroid Build Coastguard Worker         if (pthread_mutex_lock(&dlmutex))
221*7c568831SAndroid Build Coastguard Worker                 return;
222*7c568831SAndroid Build Coastguard Worker 
223*7c568831SAndroid Build Coastguard Worker         if (p)
224*7c568831SAndroid Build Coastguard Worker                 p->lockcount++;
225*7c568831SAndroid Build Coastguard Worker }
226*7c568831SAndroid Build Coastguard Worker 
227*7c568831SAndroid Build Coastguard Worker 
228*7c568831SAndroid Build Coastguard Worker static void
dlunlock(void)229*7c568831SAndroid Build Coastguard Worker dlunlock(void)
230*7c568831SAndroid Build Coastguard Worker 
231*7c568831SAndroid Build Coastguard Worker {
232*7c568831SAndroid Build Coastguard Worker         dlts_t * p;
233*7c568831SAndroid Build Coastguard Worker 
234*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & THREADS))
235*7c568831SAndroid Build Coastguard Worker                 return;
236*7c568831SAndroid Build Coastguard Worker 
237*7c568831SAndroid Build Coastguard Worker         if (dlflags & MULTIBUF) {
238*7c568831SAndroid Build Coastguard Worker                 p = pthread_getspecific(dlkey);
239*7c568831SAndroid Build Coastguard Worker 
240*7c568831SAndroid Build Coastguard Worker                 if (p && p->lockcount > 1) {
241*7c568831SAndroid Build Coastguard Worker                         p->lockcount--;
242*7c568831SAndroid Build Coastguard Worker                         return;
243*7c568831SAndroid Build Coastguard Worker                         }
244*7c568831SAndroid Build Coastguard Worker                 }
245*7c568831SAndroid Build Coastguard Worker         else
246*7c568831SAndroid Build Coastguard Worker                 p = (dlts_t *) NULL;
247*7c568831SAndroid Build Coastguard Worker 
248*7c568831SAndroid Build Coastguard Worker         if (pthread_mutex_unlock(&dlmutex))
249*7c568831SAndroid Build Coastguard Worker                 return;
250*7c568831SAndroid Build Coastguard Worker 
251*7c568831SAndroid Build Coastguard Worker         if (p)
252*7c568831SAndroid Build Coastguard Worker                 p->lockcount--;
253*7c568831SAndroid Build Coastguard Worker }
254*7c568831SAndroid Build Coastguard Worker 
255*7c568831SAndroid Build Coastguard Worker 
256*7c568831SAndroid Build Coastguard Worker const char *
dlerror(void)257*7c568831SAndroid Build Coastguard Worker dlerror(void)
258*7c568831SAndroid Build Coastguard Worker 
259*7c568831SAndroid Build Coastguard Worker {
260*7c568831SAndroid Build Coastguard Worker         dlts_t * p;
261*7c568831SAndroid Build Coastguard Worker 
262*7c568831SAndroid Build Coastguard Worker         dlthreadinit();
263*7c568831SAndroid Build Coastguard Worker 
264*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & MULTIBUF))
265*7c568831SAndroid Build Coastguard Worker                 p = &static_buf;
266*7c568831SAndroid Build Coastguard Worker         else if (!(p = (dlts_t *) pthread_getspecific(dlkey)))
267*7c568831SAndroid Build Coastguard Worker                 p = &static_buf;
268*7c568831SAndroid Build Coastguard Worker 
269*7c568831SAndroid Build Coastguard Worker         if (!p->iserror)
270*7c568831SAndroid Build Coastguard Worker                 return (const char *) NULL;
271*7c568831SAndroid Build Coastguard Worker 
272*7c568831SAndroid Build Coastguard Worker         p->iserror = 0;
273*7c568831SAndroid Build Coastguard Worker         return p->str;
274*7c568831SAndroid Build Coastguard Worker }
275*7c568831SAndroid Build Coastguard Worker 
276*7c568831SAndroid Build Coastguard Worker 
277*7c568831SAndroid Build Coastguard Worker static void
dlseterror_from_errno(unsigned int err_no)278*7c568831SAndroid Build Coastguard Worker dlseterror_from_errno(unsigned int err_no)
279*7c568831SAndroid Build Coastguard Worker 
280*7c568831SAndroid Build Coastguard Worker {
281*7c568831SAndroid Build Coastguard Worker         dlts_t * p;
282*7c568831SAndroid Build Coastguard Worker 
283*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & MULTIBUF))
284*7c568831SAndroid Build Coastguard Worker                 p = &static_buf;
285*7c568831SAndroid Build Coastguard Worker         else if (!(p = (dlts_t *) pthread_getspecific(dlkey)))
286*7c568831SAndroid Build Coastguard Worker                 p = &static_buf;
287*7c568831SAndroid Build Coastguard Worker 
288*7c568831SAndroid Build Coastguard Worker         strcpy(p->str, strerror(err_no));
289*7c568831SAndroid Build Coastguard Worker         p->iserror = 1;
290*7c568831SAndroid Build Coastguard Worker }
291*7c568831SAndroid Build Coastguard Worker 
292*7c568831SAndroid Build Coastguard Worker 
293*7c568831SAndroid Build Coastguard Worker static void
dlseterror_from_exception(volatile _INTRPT_Hndlr_Parms_T * excp)294*7c568831SAndroid Build Coastguard Worker dlseterror_from_exception(volatile _INTRPT_Hndlr_Parms_T * excp)
295*7c568831SAndroid Build Coastguard Worker 
296*7c568831SAndroid Build Coastguard Worker {
297*7c568831SAndroid Build Coastguard Worker         int i;
298*7c568831SAndroid Build Coastguard Worker         Qmh_Rtvm_RTVM0300_t * imp;
299*7c568831SAndroid Build Coastguard Worker         char * cp;
300*7c568831SAndroid Build Coastguard Worker         _INTRPT_Hndlr_Parms_T * p;
301*7c568831SAndroid Build Coastguard Worker         dlts_t * q;
302*7c568831SAndroid Build Coastguard Worker         char rtvmbuf[30000];
303*7c568831SAndroid Build Coastguard Worker         Qus_EC_t errinfo;
304*7c568831SAndroid Build Coastguard Worker 
305*7c568831SAndroid Build Coastguard Worker         p = (_INTRPT_Hndlr_Parms_T *) excp;
306*7c568831SAndroid Build Coastguard Worker         errinfo.Bytes_Provided = 0;             /* Exception on error. */
307*7c568831SAndroid Build Coastguard Worker         QMHRTVM(rtvmbuf, sizeof rtvmbuf, "RTVM0300", p->Msg_Id,
308*7c568831SAndroid Build Coastguard Worker             "QCPFMSG   QSYS      ", p->Ex_Data, p->Msg_Data_Len,
309*7c568831SAndroid Build Coastguard Worker             "*YES      ", "*NO       ", &errinfo);
310*7c568831SAndroid Build Coastguard Worker         imp = offset_by(Qmh_Rtvm_RTVM0300_t, rtvmbuf, 0);
311*7c568831SAndroid Build Coastguard Worker 
312*7c568831SAndroid Build Coastguard Worker         if (!(dlflags & MULTIBUF))
313*7c568831SAndroid Build Coastguard Worker                 q = &static_buf;
314*7c568831SAndroid Build Coastguard Worker         else if (!(q = (dlts_t *) pthread_getspecific(dlkey)))
315*7c568831SAndroid Build Coastguard Worker                 q = &static_buf;
316*7c568831SAndroid Build Coastguard Worker 
317*7c568831SAndroid Build Coastguard Worker         if (i = imp->Length_Message_Returned)
318*7c568831SAndroid Build Coastguard Worker                 cp = offset_by(char, imp, imp->Offset_Message_Returned);
319*7c568831SAndroid Build Coastguard Worker         else if (i = imp->Length_Help_Returned)
320*7c568831SAndroid Build Coastguard Worker                 cp = offset_by(char, imp, imp->Offset_Help_Returned);
321*7c568831SAndroid Build Coastguard Worker         else {
322*7c568831SAndroid Build Coastguard Worker                 q->iserror = 0;
323*7c568831SAndroid Build Coastguard Worker                 return;
324*7c568831SAndroid Build Coastguard Worker                 }
325*7c568831SAndroid Build Coastguard Worker 
326*7c568831SAndroid Build Coastguard Worker         q->iserror = 1;
327*7c568831SAndroid Build Coastguard Worker 
328*7c568831SAndroid Build Coastguard Worker         if (i > sizeof q->str - 1)
329*7c568831SAndroid Build Coastguard Worker                 i = sizeof q->str - 1;
330*7c568831SAndroid Build Coastguard Worker 
331*7c568831SAndroid Build Coastguard Worker         memcpy(q->str, cp, i);
332*7c568831SAndroid Build Coastguard Worker         q->str[i] = '\0';
333*7c568831SAndroid Build Coastguard Worker }
334*7c568831SAndroid Build Coastguard Worker 
335*7c568831SAndroid Build Coastguard Worker 
336*7c568831SAndroid Build Coastguard Worker static int
dlparentpath(const char * path,size_t len)337*7c568831SAndroid Build Coastguard Worker dlparentpath(const char * path, size_t len)
338*7c568831SAndroid Build Coastguard Worker 
339*7c568831SAndroid Build Coastguard Worker {
340*7c568831SAndroid Build Coastguard Worker         if (len <= 1)
341*7c568831SAndroid Build Coastguard Worker                 return len;
342*7c568831SAndroid Build Coastguard Worker 
343*7c568831SAndroid Build Coastguard Worker         while (path[--len] != '/')
344*7c568831SAndroid Build Coastguard Worker                 ;
345*7c568831SAndroid Build Coastguard Worker 
346*7c568831SAndroid Build Coastguard Worker         return len? len: 1;
347*7c568831SAndroid Build Coastguard Worker }
348*7c568831SAndroid Build Coastguard Worker 
349*7c568831SAndroid Build Coastguard Worker 
350*7c568831SAndroid Build Coastguard Worker static int
dlmakepath(char * path,size_t pathlen,const char * tail,size_t taillen)351*7c568831SAndroid Build Coastguard Worker dlmakepath(char * path, size_t pathlen, const char * tail, size_t taillen)
352*7c568831SAndroid Build Coastguard Worker 
353*7c568831SAndroid Build Coastguard Worker {
354*7c568831SAndroid Build Coastguard Worker         int i;
355*7c568831SAndroid Build Coastguard Worker 
356*7c568831SAndroid Build Coastguard Worker         if (taillen && tail[0] == '/')
357*7c568831SAndroid Build Coastguard Worker                 pathlen = 0;
358*7c568831SAndroid Build Coastguard Worker 
359*7c568831SAndroid Build Coastguard Worker         for (;;) {
360*7c568831SAndroid Build Coastguard Worker                 while (taillen && *tail == '/') {
361*7c568831SAndroid Build Coastguard Worker                         tail++;
362*7c568831SAndroid Build Coastguard Worker                         taillen--;
363*7c568831SAndroid Build Coastguard Worker                         }
364*7c568831SAndroid Build Coastguard Worker 
365*7c568831SAndroid Build Coastguard Worker                 if (!taillen)
366*7c568831SAndroid Build Coastguard Worker                         break;
367*7c568831SAndroid Build Coastguard Worker 
368*7c568831SAndroid Build Coastguard Worker                 for (i = 0; i < taillen; i++)
369*7c568831SAndroid Build Coastguard Worker                         if (tail[i] == '/')
370*7c568831SAndroid Build Coastguard Worker                                 break;
371*7c568831SAndroid Build Coastguard Worker 
372*7c568831SAndroid Build Coastguard Worker                 if (*tail == '.')
373*7c568831SAndroid Build Coastguard Worker                         switch (i) {
374*7c568831SAndroid Build Coastguard Worker 
375*7c568831SAndroid Build Coastguard Worker                         case 2:
376*7c568831SAndroid Build Coastguard Worker                                 if (tail[1] != '.')
377*7c568831SAndroid Build Coastguard Worker                                         break;
378*7c568831SAndroid Build Coastguard Worker 
379*7c568831SAndroid Build Coastguard Worker                                 pathlen = dlparentpath(path, pathlen);
380*7c568831SAndroid Build Coastguard Worker 
381*7c568831SAndroid Build Coastguard Worker                         case 1:
382*7c568831SAndroid Build Coastguard Worker                                 tail += i;
383*7c568831SAndroid Build Coastguard Worker                                 taillen -= i;
384*7c568831SAndroid Build Coastguard Worker                                 continue;
385*7c568831SAndroid Build Coastguard Worker                                 }
386*7c568831SAndroid Build Coastguard Worker 
387*7c568831SAndroid Build Coastguard Worker                 if (pathlen + i + 1 >= MAXPATHLEN) {
388*7c568831SAndroid Build Coastguard Worker                         errno = ENAMETOOLONG;
389*7c568831SAndroid Build Coastguard Worker                         return -1;
390*7c568831SAndroid Build Coastguard Worker                         }
391*7c568831SAndroid Build Coastguard Worker 
392*7c568831SAndroid Build Coastguard Worker                 path[pathlen++] = '/';
393*7c568831SAndroid Build Coastguard Worker                 memcpy(path + pathlen, tail, i);
394*7c568831SAndroid Build Coastguard Worker                 pathlen += i;
395*7c568831SAndroid Build Coastguard Worker                 }
396*7c568831SAndroid Build Coastguard Worker 
397*7c568831SAndroid Build Coastguard Worker         if (!pathlen)
398*7c568831SAndroid Build Coastguard Worker                 path[pathlen++] = '/';
399*7c568831SAndroid Build Coastguard Worker 
400*7c568831SAndroid Build Coastguard Worker         path[pathlen] = '\0';
401*7c568831SAndroid Build Coastguard Worker         return pathlen;
402*7c568831SAndroid Build Coastguard Worker }
403*7c568831SAndroid Build Coastguard Worker 
404*7c568831SAndroid Build Coastguard Worker 
405*7c568831SAndroid Build Coastguard Worker static int
dlresolveLink(const char * path,char * buf,size_t bufsiz)406*7c568831SAndroid Build Coastguard Worker dlresolveLink(const char * path, char * buf, size_t bufsiz)
407*7c568831SAndroid Build Coastguard Worker 
408*7c568831SAndroid Build Coastguard Worker {
409*7c568831SAndroid Build Coastguard Worker         int n;
410*7c568831SAndroid Build Coastguard Worker         int l1;
411*7c568831SAndroid Build Coastguard Worker         int l2;
412*7c568831SAndroid Build Coastguard Worker         struct stat sbuf;
413*7c568831SAndroid Build Coastguard Worker         char buf1[MAXPATHLEN + 1];
414*7c568831SAndroid Build Coastguard Worker         char buf2[MAXPATHLEN + 1];
415*7c568831SAndroid Build Coastguard Worker 
416*7c568831SAndroid Build Coastguard Worker         /**
417*7c568831SAndroid Build Coastguard Worker         ***     Resolve symbolic link to IFS object name.
418*7c568831SAndroid Build Coastguard Worker         **/
419*7c568831SAndroid Build Coastguard Worker 
420*7c568831SAndroid Build Coastguard Worker         if (!buf) {
421*7c568831SAndroid Build Coastguard Worker                 errno = EFAULT;
422*7c568831SAndroid Build Coastguard Worker                 return -1;
423*7c568831SAndroid Build Coastguard Worker                 }
424*7c568831SAndroid Build Coastguard Worker 
425*7c568831SAndroid Build Coastguard Worker         if (!path || !*path || !bufsiz) {
426*7c568831SAndroid Build Coastguard Worker                 errno = EINVAL;
427*7c568831SAndroid Build Coastguard Worker                 return -1;
428*7c568831SAndroid Build Coastguard Worker                 }
429*7c568831SAndroid Build Coastguard Worker 
430*7c568831SAndroid Build Coastguard Worker         if (*path != '/') {
431*7c568831SAndroid Build Coastguard Worker                 if (!getcwd(buf1, sizeof buf1))
432*7c568831SAndroid Build Coastguard Worker                         return -1;
433*7c568831SAndroid Build Coastguard Worker 
434*7c568831SAndroid Build Coastguard Worker                 l1 = strlen(buf1);
435*7c568831SAndroid Build Coastguard Worker                 }
436*7c568831SAndroid Build Coastguard Worker         else
437*7c568831SAndroid Build Coastguard Worker                 l1 = 0;
438*7c568831SAndroid Build Coastguard Worker 
439*7c568831SAndroid Build Coastguard Worker         l1 = dlmakepath(buf1, l1, path, strlen(path));
440*7c568831SAndroid Build Coastguard Worker         n = 0;
441*7c568831SAndroid Build Coastguard Worker 
442*7c568831SAndroid Build Coastguard Worker         for (;;) {
443*7c568831SAndroid Build Coastguard Worker                 if (l1 < 0)
444*7c568831SAndroid Build Coastguard Worker                         return -1;
445*7c568831SAndroid Build Coastguard Worker 
446*7c568831SAndroid Build Coastguard Worker                 if (n++ >= 256) {
447*7c568831SAndroid Build Coastguard Worker                         errno = ELOOP;
448*7c568831SAndroid Build Coastguard Worker                         return -1;
449*7c568831SAndroid Build Coastguard Worker                         }
450*7c568831SAndroid Build Coastguard Worker 
451*7c568831SAndroid Build Coastguard Worker                 if (lstat(buf1, &sbuf)) {
452*7c568831SAndroid Build Coastguard Worker                         if (errno == ENOENT)
453*7c568831SAndroid Build Coastguard Worker                                 break;
454*7c568831SAndroid Build Coastguard Worker 
455*7c568831SAndroid Build Coastguard Worker                         return -1;
456*7c568831SAndroid Build Coastguard Worker                         }
457*7c568831SAndroid Build Coastguard Worker 
458*7c568831SAndroid Build Coastguard Worker                 if (!S_ISLNK(sbuf.st_mode))
459*7c568831SAndroid Build Coastguard Worker                         break;
460*7c568831SAndroid Build Coastguard Worker 
461*7c568831SAndroid Build Coastguard Worker                 if (sbuf.st_size > MAXPATHLEN) {
462*7c568831SAndroid Build Coastguard Worker                         errno = ENAMETOOLONG;
463*7c568831SAndroid Build Coastguard Worker                         return -1;
464*7c568831SAndroid Build Coastguard Worker                         }
465*7c568831SAndroid Build Coastguard Worker 
466*7c568831SAndroid Build Coastguard Worker                 l2 = readlink(buf1, buf2, MAXPATHLEN + 1);
467*7c568831SAndroid Build Coastguard Worker 
468*7c568831SAndroid Build Coastguard Worker                 if (l2 < 0)
469*7c568831SAndroid Build Coastguard Worker                         return -1;
470*7c568831SAndroid Build Coastguard Worker 
471*7c568831SAndroid Build Coastguard Worker                 if (buf2[0] != '/')
472*7c568831SAndroid Build Coastguard Worker                         l1 = dlparentpath(buf1, l1);
473*7c568831SAndroid Build Coastguard Worker 
474*7c568831SAndroid Build Coastguard Worker                 l1 = dlmakepath(buf1, l1, buf2, l2);
475*7c568831SAndroid Build Coastguard Worker                 }
476*7c568831SAndroid Build Coastguard Worker 
477*7c568831SAndroid Build Coastguard Worker         if (l1 >= bufsiz) {
478*7c568831SAndroid Build Coastguard Worker                 errno = ENAMETOOLONG;
479*7c568831SAndroid Build Coastguard Worker                 return -1;
480*7c568831SAndroid Build Coastguard Worker                 }
481*7c568831SAndroid Build Coastguard Worker 
482*7c568831SAndroid Build Coastguard Worker         memcpy(buf, buf1, l1 + 1);
483*7c568831SAndroid Build Coastguard Worker         return l1;
484*7c568831SAndroid Build Coastguard Worker }
485*7c568831SAndroid Build Coastguard Worker 
486*7c568831SAndroid Build Coastguard Worker 
487*7c568831SAndroid Build Coastguard Worker static int
dlGetObjectName(Qp0l_QSYS_Info_t * qsysinfo,const char * dir,int dirlen,const char * link)488*7c568831SAndroid Build Coastguard Worker dlGetObjectName(Qp0l_QSYS_Info_t * qsysinfo, const char * dir,
489*7c568831SAndroid Build Coastguard Worker                         int dirlen, const char * link)
490*7c568831SAndroid Build Coastguard Worker 
491*7c568831SAndroid Build Coastguard Worker {
492*7c568831SAndroid Build Coastguard Worker         int n;
493*7c568831SAndroid Build Coastguard Worker         char * namebuf;
494*7c568831SAndroid Build Coastguard Worker         Qlg_Path_Name_T * qptp;
495*7c568831SAndroid Build Coastguard Worker         char pathbuf[sizeof(Qlg_Path_Name_T) + _QP0L_DIR_NAME_LG + 4];
496*7c568831SAndroid Build Coastguard Worker         Qus_EC_t errinfo;
497*7c568831SAndroid Build Coastguard Worker         struct stat sbuf;
498*7c568831SAndroid Build Coastguard Worker 
499*7c568831SAndroid Build Coastguard Worker         /**
500*7c568831SAndroid Build Coastguard Worker         ***     Get QSYS object library/name/member and type corresponding to
501*7c568831SAndroid Build Coastguard Worker         ***             the symbolic `link' in directory `dir'.
502*7c568831SAndroid Build Coastguard Worker         **/
503*7c568831SAndroid Build Coastguard Worker 
504*7c568831SAndroid Build Coastguard Worker         if (!qsysinfo) {
505*7c568831SAndroid Build Coastguard Worker                 errno = EFAULT;
506*7c568831SAndroid Build Coastguard Worker                 return -1;
507*7c568831SAndroid Build Coastguard Worker                 }
508*7c568831SAndroid Build Coastguard Worker 
509*7c568831SAndroid Build Coastguard Worker         if (!dir && !link) {
510*7c568831SAndroid Build Coastguard Worker                 errno = EINVAL;
511*7c568831SAndroid Build Coastguard Worker                 return -1;
512*7c568831SAndroid Build Coastguard Worker                 }
513*7c568831SAndroid Build Coastguard Worker 
514*7c568831SAndroid Build Coastguard Worker         qptp = (Qlg_Path_Name_T *) pathbuf;
515*7c568831SAndroid Build Coastguard Worker         namebuf = pathbuf + sizeof(Qlg_Path_Name_T);
516*7c568831SAndroid Build Coastguard Worker         n = 0;
517*7c568831SAndroid Build Coastguard Worker 
518*7c568831SAndroid Build Coastguard Worker         /**
519*7c568831SAndroid Build Coastguard Worker         ***     Build full path.
520*7c568831SAndroid Build Coastguard Worker         **/
521*7c568831SAndroid Build Coastguard Worker 
522*7c568831SAndroid Build Coastguard Worker         if (dir) {
523*7c568831SAndroid Build Coastguard Worker                 if (dirlen < 0 || dirlen > _QP0L_DIR_NAME_LG + 4)
524*7c568831SAndroid Build Coastguard Worker                         dirlen = _QP0L_DIR_NAME_LG + 4;
525*7c568831SAndroid Build Coastguard Worker 
526*7c568831SAndroid Build Coastguard Worker                 while (*dir && n < dirlen)
527*7c568831SAndroid Build Coastguard Worker                         namebuf[n++] = *dir++;
528*7c568831SAndroid Build Coastguard Worker                 }
529*7c568831SAndroid Build Coastguard Worker 
530*7c568831SAndroid Build Coastguard Worker         if (n && namebuf[n - 1] == '/')
531*7c568831SAndroid Build Coastguard Worker                 n--;
532*7c568831SAndroid Build Coastguard Worker 
533*7c568831SAndroid Build Coastguard Worker         if (link) {
534*7c568831SAndroid Build Coastguard Worker                 if (*link && *link != '/' && n < _QP0L_DIR_NAME_LG + 4)
535*7c568831SAndroid Build Coastguard Worker                         namebuf[n++] = '/';
536*7c568831SAndroid Build Coastguard Worker 
537*7c568831SAndroid Build Coastguard Worker                 while (*link && n < _QP0L_DIR_NAME_LG + 4)
538*7c568831SAndroid Build Coastguard Worker                         namebuf[n++] = *link++;
539*7c568831SAndroid Build Coastguard Worker                 }
540*7c568831SAndroid Build Coastguard Worker 
541*7c568831SAndroid Build Coastguard Worker         if (!n || n > _QP0L_DIR_NAME_LG) {
542*7c568831SAndroid Build Coastguard Worker                 errno = ENAMETOOLONG;
543*7c568831SAndroid Build Coastguard Worker                 return -1;
544*7c568831SAndroid Build Coastguard Worker                 }
545*7c568831SAndroid Build Coastguard Worker 
546*7c568831SAndroid Build Coastguard Worker         namebuf[n] = '\0';
547*7c568831SAndroid Build Coastguard Worker         n = dlresolveLink(namebuf, namebuf, _QP0L_DIR_NAME_LG + 1);
548*7c568831SAndroid Build Coastguard Worker 
549*7c568831SAndroid Build Coastguard Worker         if (n == -1)
550*7c568831SAndroid Build Coastguard Worker                 return -1;
551*7c568831SAndroid Build Coastguard Worker 
552*7c568831SAndroid Build Coastguard Worker         if (stat(namebuf, &sbuf))
553*7c568831SAndroid Build Coastguard Worker                 return -1;
554*7c568831SAndroid Build Coastguard Worker 
555*7c568831SAndroid Build Coastguard Worker         memset((char *) qptp, 0, sizeof *qptp);
556*7c568831SAndroid Build Coastguard Worker         qptp->Path_Length = n;
557*7c568831SAndroid Build Coastguard Worker         qptp->Path_Name_Delimiter[0] = '/';
558*7c568831SAndroid Build Coastguard Worker         errinfo.Bytes_Provided = sizeof errinfo;
559*7c568831SAndroid Build Coastguard Worker         Qp0lCvtPathToQSYSObjName(qptp, qsysinfo, "QSYS0100", sizeof *qsysinfo,
560*7c568831SAndroid Build Coastguard Worker             0, &errinfo);
561*7c568831SAndroid Build Coastguard Worker         return errinfo.Bytes_Available? -1: 0;
562*7c568831SAndroid Build Coastguard Worker }
563*7c568831SAndroid Build Coastguard Worker 
564*7c568831SAndroid Build Coastguard Worker 
565*7c568831SAndroid Build Coastguard Worker static const char *
getcomponent(char * dst,const char * src)566*7c568831SAndroid Build Coastguard Worker getcomponent(char * dst, const char * src)
567*7c568831SAndroid Build Coastguard Worker 
568*7c568831SAndroid Build Coastguard Worker {
569*7c568831SAndroid Build Coastguard Worker         int i;
570*7c568831SAndroid Build Coastguard Worker 
571*7c568831SAndroid Build Coastguard Worker         /**
572*7c568831SAndroid Build Coastguard Worker         ***     Get a path component of at most 10 characters and
573*7c568831SAndroid Build Coastguard Worker         ***             map it to upper case.
574*7c568831SAndroid Build Coastguard Worker         ***     Return the address of the next delimiter in source.
575*7c568831SAndroid Build Coastguard Worker         **/
576*7c568831SAndroid Build Coastguard Worker 
577*7c568831SAndroid Build Coastguard Worker         for (i = 0;; src++) {
578*7c568831SAndroid Build Coastguard Worker                 if (!*src || *src == ' ' || *src == '/') {
579*7c568831SAndroid Build Coastguard Worker                         *dst = '\0';
580*7c568831SAndroid Build Coastguard Worker                         return src;
581*7c568831SAndroid Build Coastguard Worker                         }
582*7c568831SAndroid Build Coastguard Worker 
583*7c568831SAndroid Build Coastguard Worker                 if (i < 10) {
584*7c568831SAndroid Build Coastguard Worker                         *dst++ = toupper(*src);
585*7c568831SAndroid Build Coastguard Worker                         i++;
586*7c568831SAndroid Build Coastguard Worker                         }
587*7c568831SAndroid Build Coastguard Worker                 }
588*7c568831SAndroid Build Coastguard Worker }
589*7c568831SAndroid Build Coastguard Worker 
590*7c568831SAndroid Build Coastguard Worker 
591*7c568831SAndroid Build Coastguard Worker static int
dlpath2QSYS(Qp0l_QSYS_Info_t * qsysinfo,const char * path,const char * dftlib)592*7c568831SAndroid Build Coastguard Worker dlpath2QSYS(Qp0l_QSYS_Info_t * qsysinfo, const char * path, const char * dftlib)
593*7c568831SAndroid Build Coastguard Worker 
594*7c568831SAndroid Build Coastguard Worker {
595*7c568831SAndroid Build Coastguard Worker         unsigned int flags;
596*7c568831SAndroid Build Coastguard Worker         char * cp;
597*7c568831SAndroid Build Coastguard Worker 
598*7c568831SAndroid Build Coastguard Worker         /**
599*7c568831SAndroid Build Coastguard Worker         ***     Convert the given path to a QSYS object name.
600*7c568831SAndroid Build Coastguard Worker         ***     Syntax rules for paths are:
601*7c568831SAndroid Build Coastguard Worker         ***
602*7c568831SAndroid Build Coastguard Worker         ***     '/'+ [ <library> [  '/'+ <file> [ '/'+ <member> ] ] '/'* ]
603*7c568831SAndroid Build Coastguard Worker         ***     <library> '/'+ <file> [ '/'+ <member> ] '/'*
604*7c568831SAndroid Build Coastguard Worker         ***     <file> '/'*
605*7c568831SAndroid Build Coastguard Worker         ***
606*7c568831SAndroid Build Coastguard Worker         ***     If default library is not given, *LIBL is assumed.
607*7c568831SAndroid Build Coastguard Worker         ***     Components may no contain spaces. They are translated to
608*7c568831SAndroid Build Coastguard Worker         ***             uppercase. Only the first 10 characters are significant.
609*7c568831SAndroid Build Coastguard Worker         ***     There is no check for the validity of the given components and
610*7c568831SAndroid Build Coastguard Worker         ***             for the object existence.
611*7c568831SAndroid Build Coastguard Worker         ***     Component types are not in the path, but generated internally.
612*7c568831SAndroid Build Coastguard Worker         ***     CCSID is not processed.
613*7c568831SAndroid Build Coastguard Worker         ***
614*7c568831SAndroid Build Coastguard Worker         ***     Return 0 upon success, else -1.
615*7c568831SAndroid Build Coastguard Worker         **/
616*7c568831SAndroid Build Coastguard Worker 
617*7c568831SAndroid Build Coastguard Worker         if (!qsysinfo || !path) {
618*7c568831SAndroid Build Coastguard Worker                 errno = EFAULT;
619*7c568831SAndroid Build Coastguard Worker                 return -1;
620*7c568831SAndroid Build Coastguard Worker                 }
621*7c568831SAndroid Build Coastguard Worker 
622*7c568831SAndroid Build Coastguard Worker         /**
623*7c568831SAndroid Build Coastguard Worker         ***     Strip leading spaces.
624*7c568831SAndroid Build Coastguard Worker         **/
625*7c568831SAndroid Build Coastguard Worker 
626*7c568831SAndroid Build Coastguard Worker         while (*path == ' ')
627*7c568831SAndroid Build Coastguard Worker                 path++;
628*7c568831SAndroid Build Coastguard Worker 
629*7c568831SAndroid Build Coastguard Worker         /**
630*7c568831SAndroid Build Coastguard Worker         ***     Check for null path.
631*7c568831SAndroid Build Coastguard Worker         **/
632*7c568831SAndroid Build Coastguard Worker 
633*7c568831SAndroid Build Coastguard Worker         if (!*path) {
634*7c568831SAndroid Build Coastguard Worker                 errno = EINVAL;
635*7c568831SAndroid Build Coastguard Worker                 return -1;
636*7c568831SAndroid Build Coastguard Worker                 }
637*7c568831SAndroid Build Coastguard Worker 
638*7c568831SAndroid Build Coastguard Worker         /**
639*7c568831SAndroid Build Coastguard Worker         ***     Preset the result structure.
640*7c568831SAndroid Build Coastguard Worker         **/
641*7c568831SAndroid Build Coastguard Worker 
642*7c568831SAndroid Build Coastguard Worker         memset((char *) qsysinfo, 0, sizeof *qsysinfo);
643*7c568831SAndroid Build Coastguard Worker 
644*7c568831SAndroid Build Coastguard Worker         /**
645*7c568831SAndroid Build Coastguard Worker         ***     Determine the format.
646*7c568831SAndroid Build Coastguard Worker         **/
647*7c568831SAndroid Build Coastguard Worker 
648*7c568831SAndroid Build Coastguard Worker         if (*path == '/') {
649*7c568831SAndroid Build Coastguard Worker                 /**
650*7c568831SAndroid Build Coastguard Worker                 ***     Library component present.
651*7c568831SAndroid Build Coastguard Worker                 **/
652*7c568831SAndroid Build Coastguard Worker 
653*7c568831SAndroid Build Coastguard Worker                 while (*++path == '/')
654*7c568831SAndroid Build Coastguard Worker                         ;
655*7c568831SAndroid Build Coastguard Worker 
656*7c568831SAndroid Build Coastguard Worker                 if (!*path || *path == ' ')
657*7c568831SAndroid Build Coastguard Worker                         strcpy(qsysinfo->Lib_Name, "QSYS");
658*7c568831SAndroid Build Coastguard Worker                 else
659*7c568831SAndroid Build Coastguard Worker                         path = getcomponent(qsysinfo->Lib_Name, path);
660*7c568831SAndroid Build Coastguard Worker 
661*7c568831SAndroid Build Coastguard Worker                 /**
662*7c568831SAndroid Build Coastguard Worker                 ***     Check for file component and get it.
663*7c568831SAndroid Build Coastguard Worker                 **/
664*7c568831SAndroid Build Coastguard Worker 
665*7c568831SAndroid Build Coastguard Worker                 if (*path == '/') {
666*7c568831SAndroid Build Coastguard Worker                         while (*++path == '/')
667*7c568831SAndroid Build Coastguard Worker                                 ;
668*7c568831SAndroid Build Coastguard Worker 
669*7c568831SAndroid Build Coastguard Worker                         if (*path && *path != ' ')
670*7c568831SAndroid Build Coastguard Worker                                 path = getcomponent(qsysinfo->Obj_Name, path);
671*7c568831SAndroid Build Coastguard Worker                         }
672*7c568831SAndroid Build Coastguard Worker                 }
673*7c568831SAndroid Build Coastguard Worker         else {
674*7c568831SAndroid Build Coastguard Worker                 /**
675*7c568831SAndroid Build Coastguard Worker                 ***     The mandatory component is the <file>.
676*7c568831SAndroid Build Coastguard Worker                 **/
677*7c568831SAndroid Build Coastguard Worker 
678*7c568831SAndroid Build Coastguard Worker                 path = getcomponent(qsysinfo->Obj_Name, path);
679*7c568831SAndroid Build Coastguard Worker 
680*7c568831SAndroid Build Coastguard Worker                 while (*path == '/')
681*7c568831SAndroid Build Coastguard Worker                         path++;
682*7c568831SAndroid Build Coastguard Worker 
683*7c568831SAndroid Build Coastguard Worker                 /**
684*7c568831SAndroid Build Coastguard Worker                 ***     If there is a second component, move the first to
685*7c568831SAndroid Build Coastguard Worker                 ***             the library name and parse the file name.
686*7c568831SAndroid Build Coastguard Worker                 **/
687*7c568831SAndroid Build Coastguard Worker 
688*7c568831SAndroid Build Coastguard Worker                 if (*path && *path != ' ') {
689*7c568831SAndroid Build Coastguard Worker                         strcpy(qsysinfo->Lib_Name, qsysinfo->Obj_Name);
690*7c568831SAndroid Build Coastguard Worker                         memset(qsysinfo->Obj_Name, 0,
691*7c568831SAndroid Build Coastguard Worker                             sizeof qsysinfo->Obj_Name);
692*7c568831SAndroid Build Coastguard Worker                         path = getcomponent(qsysinfo->Obj_Name, path);
693*7c568831SAndroid Build Coastguard Worker                         }
694*7c568831SAndroid Build Coastguard Worker                 else
695*7c568831SAndroid Build Coastguard Worker                         strcpy(qsysinfo->Lib_Name, dftlib? dftlib: "*LIBL");
696*7c568831SAndroid Build Coastguard Worker                 }
697*7c568831SAndroid Build Coastguard Worker 
698*7c568831SAndroid Build Coastguard Worker         /**
699*7c568831SAndroid Build Coastguard Worker         ***     Check and set-up member.
700*7c568831SAndroid Build Coastguard Worker         **/
701*7c568831SAndroid Build Coastguard Worker 
702*7c568831SAndroid Build Coastguard Worker         while (*path == '/')
703*7c568831SAndroid Build Coastguard Worker                 path++;
704*7c568831SAndroid Build Coastguard Worker 
705*7c568831SAndroid Build Coastguard Worker         if (*path && *path != ' ') {
706*7c568831SAndroid Build Coastguard Worker                 path = getcomponent(qsysinfo->Mbr_Name, path);
707*7c568831SAndroid Build Coastguard Worker                 strcpy(qsysinfo->Mbr_Type, "*MBR");
708*7c568831SAndroid Build Coastguard Worker 
709*7c568831SAndroid Build Coastguard Worker                 while (*path == '/')
710*7c568831SAndroid Build Coastguard Worker                         path++;
711*7c568831SAndroid Build Coastguard Worker                 }
712*7c568831SAndroid Build Coastguard Worker 
713*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Lib_Type, "*LIB");
714*7c568831SAndroid Build Coastguard Worker 
715*7c568831SAndroid Build Coastguard Worker         if (qsysinfo->Obj_Name[0])
716*7c568831SAndroid Build Coastguard Worker                 strcpy(qsysinfo->Obj_Type, "*FILE");
717*7c568831SAndroid Build Coastguard Worker 
718*7c568831SAndroid Build Coastguard Worker         qsysinfo->Bytes_Returned = sizeof *qsysinfo;
719*7c568831SAndroid Build Coastguard Worker         qsysinfo->Bytes_Available = sizeof *qsysinfo;
720*7c568831SAndroid Build Coastguard Worker 
721*7c568831SAndroid Build Coastguard Worker         /**
722*7c568831SAndroid Build Coastguard Worker         ***     Strip trailing spaces.
723*7c568831SAndroid Build Coastguard Worker         **/
724*7c568831SAndroid Build Coastguard Worker 
725*7c568831SAndroid Build Coastguard Worker         while (*path == ' ')
726*7c568831SAndroid Build Coastguard Worker                 path++;
727*7c568831SAndroid Build Coastguard Worker 
728*7c568831SAndroid Build Coastguard Worker         if (*path) {
729*7c568831SAndroid Build Coastguard Worker                 errno = EINVAL;
730*7c568831SAndroid Build Coastguard Worker                 return -1;
731*7c568831SAndroid Build Coastguard Worker                 }
732*7c568831SAndroid Build Coastguard Worker 
733*7c568831SAndroid Build Coastguard Worker         return 0;
734*7c568831SAndroid Build Coastguard Worker }
735*7c568831SAndroid Build Coastguard Worker 
736*7c568831SAndroid Build Coastguard Worker 
737*7c568831SAndroid Build Coastguard Worker static int
dl_ifs_link(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)738*7c568831SAndroid Build Coastguard Worker dl_ifs_link(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
739*7c568831SAndroid Build Coastguard Worker 
740*7c568831SAndroid Build Coastguard Worker {
741*7c568831SAndroid Build Coastguard Worker         /**
742*7c568831SAndroid Build Coastguard Worker         ***     If `pathname' is a link found in IFS, set `qsysinfo' to its
743*7c568831SAndroid Build Coastguard Worker         ***             DB2 name.
744*7c568831SAndroid Build Coastguard Worker         ***     Return 0 if OK, else -1.
745*7c568831SAndroid Build Coastguard Worker         **/
746*7c568831SAndroid Build Coastguard Worker 
747*7c568831SAndroid Build Coastguard Worker         return dlGetObjectName(qsysinfo, (const char *) NULL, 0, pathname);
748*7c568831SAndroid Build Coastguard Worker }
749*7c568831SAndroid Build Coastguard Worker 
750*7c568831SAndroid Build Coastguard Worker 
751*7c568831SAndroid Build Coastguard Worker static int
dl_path_link(Qp0l_QSYS_Info_t * qsysinfo,const char * pathvar,const char * filename,int (* testproc)(const Qp0l_QSYS_Info_t *))752*7c568831SAndroid Build Coastguard Worker dl_path_link(Qp0l_QSYS_Info_t * qsysinfo, const char * pathvar,
753*7c568831SAndroid Build Coastguard Worker         const char * filename, int (* testproc)(const Qp0l_QSYS_Info_t *))
754*7c568831SAndroid Build Coastguard Worker 
755*7c568831SAndroid Build Coastguard Worker {
756*7c568831SAndroid Build Coastguard Worker         const char * p;
757*7c568831SAndroid Build Coastguard Worker         const char * q;
758*7c568831SAndroid Build Coastguard Worker         unsigned int i;
759*7c568831SAndroid Build Coastguard Worker         const char * path;
760*7c568831SAndroid Build Coastguard Worker 
761*7c568831SAndroid Build Coastguard Worker         /**
762*7c568831SAndroid Build Coastguard Worker         ***     If `filename' is not a path and is a link found in one of the
763*7c568831SAndroid Build Coastguard Worker         ***             colon-separated paths in environment variable `pathvar',
764*7c568831SAndroid Build Coastguard Worker         ***             set `qsysinfo' to its DB2 name.
765*7c568831SAndroid Build Coastguard Worker         ***     Return 0 if OK, else -1.
766*7c568831SAndroid Build Coastguard Worker         **/
767*7c568831SAndroid Build Coastguard Worker 
768*7c568831SAndroid Build Coastguard Worker         i = _QP0L_DIR_NAME_LG;
769*7c568831SAndroid Build Coastguard Worker 
770*7c568831SAndroid Build Coastguard Worker         for (p = filename; *p; p++)
771*7c568831SAndroid Build Coastguard Worker                 if (*p == '/' || !--i)
772*7c568831SAndroid Build Coastguard Worker                         return -1;              /* Too long or a path. */
773*7c568831SAndroid Build Coastguard Worker 
774*7c568831SAndroid Build Coastguard Worker         /**
775*7c568831SAndroid Build Coastguard Worker         ***     Make sure we have the LD_LIBRARY_PATH environment
776*7c568831SAndroid Build Coastguard Worker         ***             variable value.
777*7c568831SAndroid Build Coastguard Worker         **/
778*7c568831SAndroid Build Coastguard Worker 
779*7c568831SAndroid Build Coastguard Worker         path = getenv(pathvar);
780*7c568831SAndroid Build Coastguard Worker 
781*7c568831SAndroid Build Coastguard Worker         if (!path)
782*7c568831SAndroid Build Coastguard Worker                 return -1;                      /* No path list. */
783*7c568831SAndroid Build Coastguard Worker 
784*7c568831SAndroid Build Coastguard Worker         /**
785*7c568831SAndroid Build Coastguard Worker         ***     Try in each path listed.
786*7c568831SAndroid Build Coastguard Worker         **/
787*7c568831SAndroid Build Coastguard Worker 
788*7c568831SAndroid Build Coastguard Worker         q = path;
789*7c568831SAndroid Build Coastguard Worker 
790*7c568831SAndroid Build Coastguard Worker         if (!*q)
791*7c568831SAndroid Build Coastguard Worker                 return -1;                      /* No path list. */
792*7c568831SAndroid Build Coastguard Worker 
793*7c568831SAndroid Build Coastguard Worker         for (;;) {
794*7c568831SAndroid Build Coastguard Worker                 for (p = q; *p && *p != ':'; p++)
795*7c568831SAndroid Build Coastguard Worker                         ;
796*7c568831SAndroid Build Coastguard Worker 
797*7c568831SAndroid Build Coastguard Worker                 if (p > q)                      /* Ignore null path. */
798*7c568831SAndroid Build Coastguard Worker                         if (!dlGetObjectName(qsysinfo, q, p - q, filename))
799*7c568831SAndroid Build Coastguard Worker                                 if (!testproc || (*testproc)(qsysinfo))
800*7c568831SAndroid Build Coastguard Worker                                         return 0;       /* Found: return. */
801*7c568831SAndroid Build Coastguard Worker 
802*7c568831SAndroid Build Coastguard Worker                 if (!*p)
803*7c568831SAndroid Build Coastguard Worker                         break;
804*7c568831SAndroid Build Coastguard Worker 
805*7c568831SAndroid Build Coastguard Worker                 q = p + 1;
806*7c568831SAndroid Build Coastguard Worker                 }
807*7c568831SAndroid Build Coastguard Worker 
808*7c568831SAndroid Build Coastguard Worker         errno = ENOENT;
809*7c568831SAndroid Build Coastguard Worker         return -1;
810*7c568831SAndroid Build Coastguard Worker }
811*7c568831SAndroid Build Coastguard Worker 
812*7c568831SAndroid Build Coastguard Worker 
813*7c568831SAndroid Build Coastguard Worker static int
dl_DB2_path(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)814*7c568831SAndroid Build Coastguard Worker dl_DB2_path(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
815*7c568831SAndroid Build Coastguard Worker 
816*7c568831SAndroid Build Coastguard Worker {
817*7c568831SAndroid Build Coastguard Worker         if (dlpath2QSYS(qsysinfo, pathname, (const char *) NULL))
818*7c568831SAndroid Build Coastguard Worker                 return -1;
819*7c568831SAndroid Build Coastguard Worker 
820*7c568831SAndroid Build Coastguard Worker         if (qsysinfo->Mbr_Type[0])
821*7c568831SAndroid Build Coastguard Worker                 return -1;      /* Service program may not have members. */
822*7c568831SAndroid Build Coastguard Worker 
823*7c568831SAndroid Build Coastguard Worker         if (!qsysinfo->Obj_Type[0])
824*7c568831SAndroid Build Coastguard Worker                 return -1;      /* Object must be specified. */
825*7c568831SAndroid Build Coastguard Worker 
826*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Obj_Type, "*SRVPGM");  /* Set our object type. */
827*7c568831SAndroid Build Coastguard Worker         return 0;
828*7c568831SAndroid Build Coastguard Worker }
829*7c568831SAndroid Build Coastguard Worker 
830*7c568831SAndroid Build Coastguard Worker 
831*7c568831SAndroid Build Coastguard Worker static int
dl_DB2_name(char * dst,const char * name)832*7c568831SAndroid Build Coastguard Worker dl_DB2_name(char * dst, const char * name)
833*7c568831SAndroid Build Coastguard Worker 
834*7c568831SAndroid Build Coastguard Worker {
835*7c568831SAndroid Build Coastguard Worker         int i;
836*7c568831SAndroid Build Coastguard Worker 
837*7c568831SAndroid Build Coastguard Worker         for (i = 0; i < 10; i++) {
838*7c568831SAndroid Build Coastguard Worker                 switch (*name) {
839*7c568831SAndroid Build Coastguard Worker 
840*7c568831SAndroid Build Coastguard Worker                 default:
841*7c568831SAndroid Build Coastguard Worker                         if (!islower(*name))
842*7c568831SAndroid Build Coastguard Worker                                 break;
843*7c568831SAndroid Build Coastguard Worker 
844*7c568831SAndroid Build Coastguard Worker                 case '\0':
845*7c568831SAndroid Build Coastguard Worker                 case '/':
846*7c568831SAndroid Build Coastguard Worker                 case ' ':
847*7c568831SAndroid Build Coastguard Worker                         return -1;
848*7c568831SAndroid Build Coastguard Worker                         }
849*7c568831SAndroid Build Coastguard Worker 
850*7c568831SAndroid Build Coastguard Worker                 *dst++ = *name++;
851*7c568831SAndroid Build Coastguard Worker                 }
852*7c568831SAndroid Build Coastguard Worker 
853*7c568831SAndroid Build Coastguard Worker         if (!i)
854*7c568831SAndroid Build Coastguard Worker                 return -1;
855*7c568831SAndroid Build Coastguard Worker 
856*7c568831SAndroid Build Coastguard Worker         *dst = '\0';
857*7c568831SAndroid Build Coastguard Worker         return 0;
858*7c568831SAndroid Build Coastguard Worker }
859*7c568831SAndroid Build Coastguard Worker 
860*7c568831SAndroid Build Coastguard Worker 
861*7c568831SAndroid Build Coastguard Worker static int
dl_qualified_object(Qp0l_QSYS_Info_t * qsysinfo,const char * pathname)862*7c568831SAndroid Build Coastguard Worker dl_qualified_object(Qp0l_QSYS_Info_t * qsysinfo, const char * pathname)
863*7c568831SAndroid Build Coastguard Worker 
864*7c568831SAndroid Build Coastguard Worker {
865*7c568831SAndroid Build Coastguard Worker         memset((char *) qsysinfo, 0, sizeof *qsysinfo);
866*7c568831SAndroid Build Coastguard Worker 
867*7c568831SAndroid Build Coastguard Worker         if (dl_DB2_name(qsysinfo->Obj_Name, pathname) ||
868*7c568831SAndroid Build Coastguard Worker             dl_DB2_name(qsysinfo->Lib_Name, pathname + 10))
869*7c568831SAndroid Build Coastguard Worker                 return -1;
870*7c568831SAndroid Build Coastguard Worker 
871*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Lib_Type, "*LIB");
872*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Obj_Type, "*SRVPGM");
873*7c568831SAndroid Build Coastguard Worker         return 0;
874*7c568831SAndroid Build Coastguard Worker }
875*7c568831SAndroid Build Coastguard Worker 
876*7c568831SAndroid Build Coastguard Worker 
877*7c568831SAndroid Build Coastguard Worker static int
dl_lib_object(Qp0l_QSYS_Info_t * qsysinfo,const char * libname,const char * pathname)878*7c568831SAndroid Build Coastguard Worker dl_lib_object(Qp0l_QSYS_Info_t * qsysinfo,
879*7c568831SAndroid Build Coastguard Worker                                 const char * libname, const char * pathname)
880*7c568831SAndroid Build Coastguard Worker 
881*7c568831SAndroid Build Coastguard Worker {
882*7c568831SAndroid Build Coastguard Worker         int i;
883*7c568831SAndroid Build Coastguard Worker         char * cp;
884*7c568831SAndroid Build Coastguard Worker 
885*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Lib_Name, libname);
886*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Lib_Type, "*LIB");
887*7c568831SAndroid Build Coastguard Worker         strcpy(qsysinfo->Obj_Type, "*SRVPGM");
888*7c568831SAndroid Build Coastguard Worker         cp = qsysinfo->Obj_Name;
889*7c568831SAndroid Build Coastguard Worker 
890*7c568831SAndroid Build Coastguard Worker         while (*pathname == ' ')
891*7c568831SAndroid Build Coastguard Worker                 pathname++;
892*7c568831SAndroid Build Coastguard Worker 
893*7c568831SAndroid Build Coastguard Worker         for (i = 0;; pathname++) {
894*7c568831SAndroid Build Coastguard Worker                 switch (*pathname) {
895*7c568831SAndroid Build Coastguard Worker 
896*7c568831SAndroid Build Coastguard Worker                 case '\0':
897*7c568831SAndroid Build Coastguard Worker                 case ' ':
898*7c568831SAndroid Build Coastguard Worker                         break;
899*7c568831SAndroid Build Coastguard Worker 
900*7c568831SAndroid Build Coastguard Worker                 case '/':
901*7c568831SAndroid Build Coastguard Worker                         return -1;
902*7c568831SAndroid Build Coastguard Worker 
903*7c568831SAndroid Build Coastguard Worker                 default:
904*7c568831SAndroid Build Coastguard Worker                         if (i < 10)
905*7c568831SAndroid Build Coastguard Worker                                 *cp++ = toupper(*pathname);
906*7c568831SAndroid Build Coastguard Worker 
907*7c568831SAndroid Build Coastguard Worker                         i++;
908*7c568831SAndroid Build Coastguard Worker                         continue;
909*7c568831SAndroid Build Coastguard Worker                         }
910*7c568831SAndroid Build Coastguard Worker 
911*7c568831SAndroid Build Coastguard Worker                 break;
912*7c568831SAndroid Build Coastguard Worker                 }
913*7c568831SAndroid Build Coastguard Worker 
914*7c568831SAndroid Build Coastguard Worker         while (*pathname == ' ')
915*7c568831SAndroid Build Coastguard Worker                 pathname++;
916*7c568831SAndroid Build Coastguard Worker 
917*7c568831SAndroid Build Coastguard Worker         if (!i || *pathname)
918*7c568831SAndroid Build Coastguard Worker                 return -1;
919*7c568831SAndroid Build Coastguard Worker 
920*7c568831SAndroid Build Coastguard Worker         *cp = '\0';
921*7c568831SAndroid Build Coastguard Worker         return 0;
922*7c568831SAndroid Build Coastguard Worker }
923*7c568831SAndroid Build Coastguard Worker 
924*7c568831SAndroid Build Coastguard Worker 
925*7c568831SAndroid Build Coastguard Worker static int
dl_is_srvpgm(const Qp0l_QSYS_Info_t * qsysinfo)926*7c568831SAndroid Build Coastguard Worker dl_is_srvpgm(const Qp0l_QSYS_Info_t * qsysinfo)
927*7c568831SAndroid Build Coastguard Worker 
928*7c568831SAndroid Build Coastguard Worker {
929*7c568831SAndroid Build Coastguard Worker         struct stat sbuf;
930*7c568831SAndroid Build Coastguard Worker         char namebuf[100];
931*7c568831SAndroid Build Coastguard Worker 
932*7c568831SAndroid Build Coastguard Worker         if (!qsysinfo->Lib_Name[0] || strcmp(qsysinfo->Lib_Type, "*LIB") ||
933*7c568831SAndroid Build Coastguard Worker             !qsysinfo->Obj_Name[0] || strcmp(qsysinfo->Obj_Type, "*SRVPGM") ||
934*7c568831SAndroid Build Coastguard Worker             qsysinfo->Mbr_Name[0] || qsysinfo->Mbr_Type[0])
935*7c568831SAndroid Build Coastguard Worker                 return 0;
936*7c568831SAndroid Build Coastguard Worker 
937*7c568831SAndroid Build Coastguard Worker         /**
938*7c568831SAndroid Build Coastguard Worker         ***     Build the IFS path name for the DB2 object.
939*7c568831SAndroid Build Coastguard Worker         **/
940*7c568831SAndroid Build Coastguard Worker 
941*7c568831SAndroid Build Coastguard Worker         sprintf(namebuf, "%s/%s.LIB/%s.SRVPGM",
942*7c568831SAndroid Build Coastguard Worker             strcmp(qsysinfo->Lib_Name, "QSYS")? "/QSYS.LIB": "",
943*7c568831SAndroid Build Coastguard Worker             qsysinfo->Lib_Name, qsysinfo->Obj_Name);
944*7c568831SAndroid Build Coastguard Worker 
945*7c568831SAndroid Build Coastguard Worker         return stat(namebuf, &sbuf) == 0;
946*7c568831SAndroid Build Coastguard Worker }
947*7c568831SAndroid Build Coastguard Worker 
948*7c568831SAndroid Build Coastguard Worker 
949*7c568831SAndroid Build Coastguard Worker static int
dlreinit(dlinfo * dlip)950*7c568831SAndroid Build Coastguard Worker dlreinit(dlinfo * dlip)
951*7c568831SAndroid Build Coastguard Worker 
952*7c568831SAndroid Build Coastguard Worker {
953*7c568831SAndroid Build Coastguard Worker         RINZ_TEMPL_T t;
954*7c568831SAndroid Build Coastguard Worker         RINZ_TEMPL_T * p;
955*7c568831SAndroid Build Coastguard Worker         volatile _INTRPT_Hndlr_Parms_T excbuf;
956*7c568831SAndroid Build Coastguard Worker 
957*7c568831SAndroid Build Coastguard Worker         if (dlip->actinfo.Flags & QLE_ABP_WAS_ACTIVE)
958*7c568831SAndroid Build Coastguard Worker                 return 0;
959*7c568831SAndroid Build Coastguard Worker 
960*7c568831SAndroid Build Coastguard Worker         /**
961*7c568831SAndroid Build Coastguard Worker         ***     Attempt to reinitialize the service program that was loaded.
962*7c568831SAndroid Build Coastguard Worker         ***     The service program must be created to allow re-initialization:
963*7c568831SAndroid Build Coastguard Worker         ***             ALWRINZ(*YES) for this to work. The default is
964*7c568831SAndroid Build Coastguard Worker         ***             ALWRINZ(*NO).
965*7c568831SAndroid Build Coastguard Worker         **/
966*7c568831SAndroid Build Coastguard Worker 
967*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(err, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
968*7c568831SAndroid Build Coastguard Worker         p = &t;
969*7c568831SAndroid Build Coastguard Worker         t.rinz_pgm = dlip->pointer;
970*7c568831SAndroid Build Coastguard Worker         t.rinz_agpmk = dlip->actinfo.Act_Grp_Mark;
971*7c568831SAndroid Build Coastguard Worker         _RINZSTAT(p);
972*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
973*7c568831SAndroid Build Coastguard Worker 
974*7c568831SAndroid Build Coastguard Worker         return 0;
975*7c568831SAndroid Build Coastguard Worker 
976*7c568831SAndroid Build Coastguard Worker err:
977*7c568831SAndroid Build Coastguard Worker         if (!memcmp((char *) excbuf.Msg_Id, "MCH4421", 7))
978*7c568831SAndroid Build Coastguard Worker                 return 0;       /* Program cannot be reinitialized. */
979*7c568831SAndroid Build Coastguard Worker 
980*7c568831SAndroid Build Coastguard Worker         dlseterror_from_exception(&excbuf);
981*7c568831SAndroid Build Coastguard Worker         return -1;
982*7c568831SAndroid Build Coastguard Worker }
983*7c568831SAndroid Build Coastguard Worker 
984*7c568831SAndroid Build Coastguard Worker 
985*7c568831SAndroid Build Coastguard Worker void *
dlsym(void * handle,const char * symbol)986*7c568831SAndroid Build Coastguard Worker dlsym(void * handle, const char * symbol)
987*7c568831SAndroid Build Coastguard Worker 
988*7c568831SAndroid Build Coastguard Worker {
989*7c568831SAndroid Build Coastguard Worker         dlinfo * dlip;
990*7c568831SAndroid Build Coastguard Worker         void * p;
991*7c568831SAndroid Build Coastguard Worker         int export_type;
992*7c568831SAndroid Build Coastguard Worker         Qus_EC_t errinfo;
993*7c568831SAndroid Build Coastguard Worker         volatile _INTRPT_Hndlr_Parms_T excbuf;
994*7c568831SAndroid Build Coastguard Worker         static int zero = 0;
995*7c568831SAndroid Build Coastguard Worker 
996*7c568831SAndroid Build Coastguard Worker         dlthreadinit();
997*7c568831SAndroid Build Coastguard Worker 
998*7c568831SAndroid Build Coastguard Worker         if (!handle || !symbol) {
999*7c568831SAndroid Build Coastguard Worker                 dlseterror_from_errno(EFAULT);
1000*7c568831SAndroid Build Coastguard Worker                 return (void *) NULL;
1001*7c568831SAndroid Build Coastguard Worker                 }
1002*7c568831SAndroid Build Coastguard Worker 
1003*7c568831SAndroid Build Coastguard Worker         dlip = (dlinfo *) handle;
1004*7c568831SAndroid Build Coastguard Worker 
1005*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1006*7c568831SAndroid Build Coastguard Worker         errinfo.Bytes_Provided = 0;
1007*7c568831SAndroid Build Coastguard Worker         QleGetExpLong(&dlip->actinfo.Act_Mark, &zero, &zero,
1008*7c568831SAndroid Build Coastguard Worker             (char *) symbol, &p, &export_type, &errinfo);
1009*7c568831SAndroid Build Coastguard Worker         return p;
1010*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1011*7c568831SAndroid Build Coastguard Worker 
1012*7c568831SAndroid Build Coastguard Worker error:
1013*7c568831SAndroid Build Coastguard Worker         dlseterror_from_exception(&excbuf);
1014*7c568831SAndroid Build Coastguard Worker         return (void *) NULL;
1015*7c568831SAndroid Build Coastguard Worker }
1016*7c568831SAndroid Build Coastguard Worker 
1017*7c568831SAndroid Build Coastguard Worker 
1018*7c568831SAndroid Build Coastguard Worker int
dlclose(void * handle)1019*7c568831SAndroid Build Coastguard Worker dlclose(void * handle)
1020*7c568831SAndroid Build Coastguard Worker 
1021*7c568831SAndroid Build Coastguard Worker {
1022*7c568831SAndroid Build Coastguard Worker         dlinfo * dlip;
1023*7c568831SAndroid Build Coastguard Worker         void (* _fini)(void);
1024*7c568831SAndroid Build Coastguard Worker 
1025*7c568831SAndroid Build Coastguard Worker         dlthreadinit();
1026*7c568831SAndroid Build Coastguard Worker 
1027*7c568831SAndroid Build Coastguard Worker         if (!handle) {
1028*7c568831SAndroid Build Coastguard Worker                 dlseterror_from_errno(EFAULT);
1029*7c568831SAndroid Build Coastguard Worker                 return -1;
1030*7c568831SAndroid Build Coastguard Worker                 }
1031*7c568831SAndroid Build Coastguard Worker 
1032*7c568831SAndroid Build Coastguard Worker         dlip = (dlinfo *) handle;
1033*7c568831SAndroid Build Coastguard Worker 
1034*7c568831SAndroid Build Coastguard Worker         if (dlip->actcount) {
1035*7c568831SAndroid Build Coastguard Worker                 if (--(dlip->actcount))
1036*7c568831SAndroid Build Coastguard Worker                         return 0;
1037*7c568831SAndroid Build Coastguard Worker 
1038*7c568831SAndroid Build Coastguard Worker                 if (_fini = dlsym(handle, "_fini"))
1039*7c568831SAndroid Build Coastguard Worker                         (*_fini)();
1040*7c568831SAndroid Build Coastguard Worker                 }
1041*7c568831SAndroid Build Coastguard Worker 
1042*7c568831SAndroid Build Coastguard Worker         return dlreinit(dlip);
1043*7c568831SAndroid Build Coastguard Worker }
1044*7c568831SAndroid Build Coastguard Worker 
1045*7c568831SAndroid Build Coastguard Worker 
1046*7c568831SAndroid Build Coastguard Worker static void *
dlopenqsys(const Qp0l_QSYS_Info_t * dllinfo)1047*7c568831SAndroid Build Coastguard Worker dlopenqsys(const Qp0l_QSYS_Info_t * dllinfo)
1048*7c568831SAndroid Build Coastguard Worker 
1049*7c568831SAndroid Build Coastguard Worker {
1050*7c568831SAndroid Build Coastguard Worker         dlinfo * dlip;
1051*7c568831SAndroid Build Coastguard Worker         dlinfo * dlip2;
1052*7c568831SAndroid Build Coastguard Worker         void (* _init)(void);
1053*7c568831SAndroid Build Coastguard Worker         unsigned int i;
1054*7c568831SAndroid Build Coastguard Worker         _SYSPTR pgmptr;
1055*7c568831SAndroid Build Coastguard Worker         unsigned long long actmark;
1056*7c568831SAndroid Build Coastguard Worker         Qus_EC_t errinfo;
1057*7c568831SAndroid Build Coastguard Worker         char actmarkstr[2 * sizeof actmark + 1];
1058*7c568831SAndroid Build Coastguard Worker         static int actinfo_size = sizeof dlip->actinfo;
1059*7c568831SAndroid Build Coastguard Worker         volatile _INTRPT_Hndlr_Parms_T excbuf;
1060*7c568831SAndroid Build Coastguard Worker 
1061*7c568831SAndroid Build Coastguard Worker         /**
1062*7c568831SAndroid Build Coastguard Worker         ***     Capture any type of error and if any occurs,
1063*7c568831SAndroid Build Coastguard Worker         ***             return not found.
1064*7c568831SAndroid Build Coastguard Worker         **/
1065*7c568831SAndroid Build Coastguard Worker 
1066*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error1, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1067*7c568831SAndroid Build Coastguard Worker         pgmptr = rslvsp(WLI_SRVPGM, (char *) dllinfo->Obj_Name,
1068*7c568831SAndroid Build Coastguard Worker             (char *) dllinfo->Lib_Name ,_AUTH_NONE);
1069*7c568831SAndroid Build Coastguard Worker 
1070*7c568831SAndroid Build Coastguard Worker         if (!pgmptr) {
1071*7c568831SAndroid Build Coastguard Worker                 errno = ENOENT;
1072*7c568831SAndroid Build Coastguard Worker                 return (void *) NULL;
1073*7c568831SAndroid Build Coastguard Worker                 }
1074*7c568831SAndroid Build Coastguard Worker 
1075*7c568831SAndroid Build Coastguard Worker         /**
1076*7c568831SAndroid Build Coastguard Worker         ***     Create a new DLL info block.
1077*7c568831SAndroid Build Coastguard Worker         **/
1078*7c568831SAndroid Build Coastguard Worker 
1079*7c568831SAndroid Build Coastguard Worker         dlip = (dlinfo *) malloc(sizeof *dlip);
1080*7c568831SAndroid Build Coastguard Worker 
1081*7c568831SAndroid Build Coastguard Worker         if (!dlip)
1082*7c568831SAndroid Build Coastguard Worker                 return (void *) NULL;           /* Cannot create block. */
1083*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1084*7c568831SAndroid Build Coastguard Worker 
1085*7c568831SAndroid Build Coastguard Worker         dllock();
1086*7c568831SAndroid Build Coastguard Worker 
1087*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error2, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1088*7c568831SAndroid Build Coastguard Worker         memset((char *) dlip, 0, sizeof *dlip);
1089*7c568831SAndroid Build Coastguard Worker         dlip->pointer = pgmptr;
1090*7c568831SAndroid Build Coastguard Worker 
1091*7c568831SAndroid Build Coastguard Worker         /**
1092*7c568831SAndroid Build Coastguard Worker         ***     Activate the DLL.
1093*7c568831SAndroid Build Coastguard Worker         **/
1094*7c568831SAndroid Build Coastguard Worker 
1095*7c568831SAndroid Build Coastguard Worker         errinfo.Bytes_Provided = 0;
1096*7c568831SAndroid Build Coastguard Worker         QleActBndPgmLong(&pgmptr, &actmark,
1097*7c568831SAndroid Build Coastguard Worker             &dlip->actinfo, &actinfo_size, &errinfo);
1098*7c568831SAndroid Build Coastguard Worker         dlip->actinfo.Act_Mark = actmark;
1099*7c568831SAndroid Build Coastguard Worker 
1100*7c568831SAndroid Build Coastguard Worker         /**
1101*7c568831SAndroid Build Coastguard Worker         ***     Dummy string encoding activation mark to use as hash table key.
1102*7c568831SAndroid Build Coastguard Worker         **/
1103*7c568831SAndroid Build Coastguard Worker 
1104*7c568831SAndroid Build Coastguard Worker         for (i = 0; actmark; actmark >>= 6)
1105*7c568831SAndroid Build Coastguard Worker                 actmarkstr[i++] = 0x40 + (actmark & 0x3F);
1106*7c568831SAndroid Build Coastguard Worker 
1107*7c568831SAndroid Build Coastguard Worker         actmarkstr[i] = '\0';
1108*7c568831SAndroid Build Coastguard Worker 
1109*7c568831SAndroid Build Coastguard Worker         /**
1110*7c568831SAndroid Build Coastguard Worker         ***     Check if already activated.
1111*7c568831SAndroid Build Coastguard Worker         **/
1112*7c568831SAndroid Build Coastguard Worker 
1113*7c568831SAndroid Build Coastguard Worker         dlip2 = (dlinfo *) xmlHashLookup(dldir, actmarkstr);
1114*7c568831SAndroid Build Coastguard Worker 
1115*7c568831SAndroid Build Coastguard Worker         if (dlip2) {
1116*7c568831SAndroid Build Coastguard Worker                 free((char *) dlip);
1117*7c568831SAndroid Build Coastguard Worker                 dlip = dlip2;
1118*7c568831SAndroid Build Coastguard Worker                 }
1119*7c568831SAndroid Build Coastguard Worker         else if (xmlHashAddEntry(dldir, (const xmlChar *) actmarkstr, dlip)) {
1120*7c568831SAndroid Build Coastguard Worker                 dlreinit(dlip);
1121*7c568831SAndroid Build Coastguard Worker                 free((char *) dlip);
1122*7c568831SAndroid Build Coastguard Worker                 dlunlock();
1123*7c568831SAndroid Build Coastguard Worker                 return (void *) NULL;
1124*7c568831SAndroid Build Coastguard Worker                 }
1125*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1126*7c568831SAndroid Build Coastguard Worker 
1127*7c568831SAndroid Build Coastguard Worker #pragma exception_handler(error2, excbuf, 0, _C2_MH_ESCAPE, _CTLA_HANDLE_NO_MSG)
1128*7c568831SAndroid Build Coastguard Worker 
1129*7c568831SAndroid Build Coastguard Worker         /**
1130*7c568831SAndroid Build Coastguard Worker         ***     Bump activation counter.
1131*7c568831SAndroid Build Coastguard Worker         **/
1132*7c568831SAndroid Build Coastguard Worker 
1133*7c568831SAndroid Build Coastguard Worker         if (!(dlip->actcount++) && (_init = dlsym(dlip, "_init")))
1134*7c568831SAndroid Build Coastguard Worker                 (*_init)();
1135*7c568831SAndroid Build Coastguard Worker 
1136*7c568831SAndroid Build Coastguard Worker         dlunlock();
1137*7c568831SAndroid Build Coastguard Worker 
1138*7c568831SAndroid Build Coastguard Worker         /**
1139*7c568831SAndroid Build Coastguard Worker         ***     Return the handle.
1140*7c568831SAndroid Build Coastguard Worker         **/
1141*7c568831SAndroid Build Coastguard Worker 
1142*7c568831SAndroid Build Coastguard Worker         return (void *) dlip;
1143*7c568831SAndroid Build Coastguard Worker #pragma disable_handler
1144*7c568831SAndroid Build Coastguard Worker 
1145*7c568831SAndroid Build Coastguard Worker error2:
1146*7c568831SAndroid Build Coastguard Worker         free((char *) dlip);
1147*7c568831SAndroid Build Coastguard Worker         dlunlock();
1148*7c568831SAndroid Build Coastguard Worker 
1149*7c568831SAndroid Build Coastguard Worker error1:
1150*7c568831SAndroid Build Coastguard Worker         dlseterror_from_exception(&excbuf);
1151*7c568831SAndroid Build Coastguard Worker         return (void *) NULL;
1152*7c568831SAndroid Build Coastguard Worker }
1153*7c568831SAndroid Build Coastguard Worker 
1154*7c568831SAndroid Build Coastguard Worker 
1155*7c568831SAndroid Build Coastguard Worker void *
dlopen(const char * filename,int flag)1156*7c568831SAndroid Build Coastguard Worker dlopen(const char * filename, int flag)
1157*7c568831SAndroid Build Coastguard Worker 
1158*7c568831SAndroid Build Coastguard Worker {
1159*7c568831SAndroid Build Coastguard Worker         void * dlhandle;
1160*7c568831SAndroid Build Coastguard Worker         int sverrno;
1161*7c568831SAndroid Build Coastguard Worker         Qp0l_QSYS_Info_t dllinfo;
1162*7c568831SAndroid Build Coastguard Worker 
1163*7c568831SAndroid Build Coastguard Worker         sverrno = errno;
1164*7c568831SAndroid Build Coastguard Worker         errno = 0;
1165*7c568831SAndroid Build Coastguard Worker 
1166*7c568831SAndroid Build Coastguard Worker         dlthreadinit();
1167*7c568831SAndroid Build Coastguard Worker 
1168*7c568831SAndroid Build Coastguard Worker         if (!filename) {
1169*7c568831SAndroid Build Coastguard Worker                 dlseterror_from_errno(EFAULT);
1170*7c568831SAndroid Build Coastguard Worker                 errno = sverrno;
1171*7c568831SAndroid Build Coastguard Worker                 return NULL;
1172*7c568831SAndroid Build Coastguard Worker                 }
1173*7c568831SAndroid Build Coastguard Worker 
1174*7c568831SAndroid Build Coastguard Worker         /**
1175*7c568831SAndroid Build Coastguard Worker         ***     Try to locate the object in the following order:
1176*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is an IFS path.
1177*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is not a path and resides in one of
1178*7c568831SAndroid Build Coastguard Worker         ***                     LD_LIBRARY_PATH colon-separated paths.
1179*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is not a path and resides in one of
1180*7c568831SAndroid Build Coastguard Worker         ***                     PATH colon-separated paths.
1181*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is a DB2 path (as /library/object).
1182*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is a qualified object name.
1183*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is an object in *CURLIB.
1184*7c568831SAndroid Build Coastguard Worker         ***     _       `filename' is an object in *LIBL.
1185*7c568831SAndroid Build Coastguard Worker         **/
1186*7c568831SAndroid Build Coastguard Worker 
1187*7c568831SAndroid Build Coastguard Worker         if (!dl_ifs_link(&dllinfo, filename) && dl_is_srvpgm(&dllinfo))
1188*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1189*7c568831SAndroid Build Coastguard Worker         else if (!dl_path_link(&dllinfo,
1190*7c568831SAndroid Build Coastguard Worker             "LD_LIBRARY_PATH", filename, dl_is_srvpgm))
1191*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1192*7c568831SAndroid Build Coastguard Worker         else if (!dl_path_link(&dllinfo, "PATH", filename, dl_is_srvpgm))
1193*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1194*7c568831SAndroid Build Coastguard Worker         else if (!dl_DB2_path(&dllinfo, filename) && dl_is_srvpgm(&dllinfo))
1195*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1196*7c568831SAndroid Build Coastguard Worker         else if (!dl_qualified_object(&dllinfo, filename) &&
1197*7c568831SAndroid Build Coastguard Worker             dl_is_srvpgm(&dllinfo))
1198*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1199*7c568831SAndroid Build Coastguard Worker         else if (!dl_lib_object(&dllinfo, "*CURLIB", filename) &&
1200*7c568831SAndroid Build Coastguard Worker             dl_is_srvpgm(&dllinfo))
1201*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1202*7c568831SAndroid Build Coastguard Worker         else if (!dl_lib_object(&dllinfo, "*LIBL", filename) &&
1203*7c568831SAndroid Build Coastguard Worker             dl_is_srvpgm(&dllinfo))
1204*7c568831SAndroid Build Coastguard Worker                 dlhandle = dlopenqsys(&dllinfo);
1205*7c568831SAndroid Build Coastguard Worker         else
1206*7c568831SAndroid Build Coastguard Worker                 dlhandle = NULL;
1207*7c568831SAndroid Build Coastguard Worker 
1208*7c568831SAndroid Build Coastguard Worker         if (!dlhandle && errno)
1209*7c568831SAndroid Build Coastguard Worker                 dlseterror_from_errno(errno);
1210*7c568831SAndroid Build Coastguard Worker 
1211*7c568831SAndroid Build Coastguard Worker         errno = sverrno;
1212*7c568831SAndroid Build Coastguard Worker         return dlhandle;
1213*7c568831SAndroid Build Coastguard Worker }
1214