Remove the RCSID macro
[openafs.git] / src / butc / butc_xbsa.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifdef xbsa
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16 #include <sys/types.h>
17 #include <afs/stds.h>
18 #include <stdio.h>
19 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
20 #include <dlfcn.h>
21 #endif
22 #include <errno.h>
23 #include "butc_xbsa.h"
24 #include <afs/butx.h>
25 #include <afs/bubasics.h>
26
27 #include "error_macros.h"
28
29 extern int debugLevel;
30
31
32 char resourceType[20] = "LFS FILE SYSTEM";
33 #define GOODSTR(s) ((s)?(s):"<NULL>")
34
35 #ifdef NEW_XBSA
36 BSA_Int16 (*XBSAInit)(long *, SecurityToken *, ObjectOwner *, char **);
37 BSA_Int16 (*XBSABeginTxn)(long);
38 BSA_Int16 (*XBSAEndTxn)(long, Vote);
39 BSA_Int16 (*XBSATerminate)(long);
40 BSA_Int16 (*XBSAQueryObject)(long, QueryDescriptor *, ObjectDescriptor *);
41 BSA_Int16 (*XBSAGetObject)(long, ObjectDescriptor *, DataBlock *);
42 BSA_Int16 (*XBSAEndData)(long);
43 BSA_Int16 (*XBSACreateObject)(long, ObjectDescriptor *, DataBlock *);
44 BSA_Int16 (*XBSADeleteObject)(long, CopyType, ObjectName *, CopyId *);
45 BSA_Int16 (*XBSAMarkObjectInactive)(long, ObjectName *);
46 BSA_Int16 (*XBSASendData)(long, DataBlock *);
47 BSA_Int16 (*XBSAGetData)(long, DataBlock *);
48 void (*XBSAQueryApiVersion)(ApiVersion *);
49 BSA_Int16 (*XBSAGetEnvironment)(long, ObjectOwner *, char **);
50 #else
51 BSA_Int16(*XBSAInit) (BSA_UInt32 *, SecurityToken *, ObjectOwner *, char **);
52 BSA_Int16(*XBSABeginTxn) (BSA_UInt32);
53 BSA_Int16(*XBSAEndTxn) (BSA_UInt32, Vote);
54 BSA_Int16(*XBSATerminate) (BSA_UInt32);
55 BSA_Int16(*XBSAQueryObject) (BSA_UInt32, QueryDescriptor *,
56                              ObjectDescriptor *);
57 BSA_Int16(*XBSAGetObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
58 BSA_Int16(*XBSAEndData) (BSA_UInt32);
59 BSA_Int16(*XBSACreateObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
60 BSA_Int16(*XBSADeleteObject) (BSA_UInt32, CopyType, ObjectName *, CopyId *);
61 BSA_Int16(*XBSAMarkObjectInactive) (BSA_UInt32, ObjectName *);
62 BSA_Int16(*XBSASendData) (BSA_UInt32, DataBlock *);
63 BSA_Int16(*XBSAGetData) (BSA_UInt32, DataBlock *);
64 BSA_Int16(*XBSAQueryApiVersion) (ApiVersion *);
65 BSA_Int16(*XBSAGetEnvironment) (BSA_UInt32, ObjectOwner *, char **);
66 #endif
67
68 xbsa_error(int rc, struct butx_transactionInfo *info)
69 {
70     switch (rc) {
71     case BSA_RC_AUTHENTICATION_FAILURE:
72         ELog(0, "     XBSA: Authentication failure\n");
73         break;
74     case BSA_RC_INVALID_KEYWORD:
75         ELog(0, "     XBSA: A specified keyword is invalid\n");
76         break;
77     case BSA_RC_TOKEN_EXPIRED:
78         ELog(0, "     XBSA: The security token has expired\n");
79         break;
80     case ADSM_RC_PSWD_GEN:
81         if (XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM) {
82             ELog(0, "     XBSA: Password generation is not supported\n");
83         }
84         break;
85     case BSA_RC_BAD_HANDLE:
86         ELog(0, "     XBSA: The handle is invalid, %d\n", info->bsaHandle);
87         break;
88     case BSA_RC_NO_MATCH:
89         ELog(0,
90              "     XBSA: There were no matches found for the specified object\n");
91         break;
92     case BSA_RC_MORE_DATA:
93         ELog(0, "     XBSA: There were more matches found than expected\n");
94         break;
95     case BSA_RC_NULL_OBJNAME:
96         ELog(0, "     XBSA: The object name is null\n");
97         break;
98     case BSA_RC_OBJNAME_TOO_LONG:
99         ELog(0, "     XBSA: The object name was longer than expected\n");
100         break;
101     case BSA_RC_DESC_TOO_LONG:
102         ELog(0,
103              "     XBSA: The description string was longer than expected\n");
104         break;
105     case BSA_RC_OBJINFO_TOO_LONG:
106         ELog(0,
107              "     XBSA: The object info string was longer than expected\n");
108         break;
109     case BSA_RC_ABORT_ACTIVE_NOT_FOUND:
110         ELog(0, "     XBSA: The specified object was not found\n");
111         break;
112     case BSA_RC_NULL_DATABLKPTR:
113         ELog(0, "     XBSA: The dataBlockPtr is null\n");
114         break;
115     case BSA_RC_INVALID_VOTE:
116         ELog(0, "     XBSA: The vote variable is invalid\n");
117         break;
118     }
119 }
120
121 /*
122  * Hook into the correct XBSA shared library.
123  * Set up the function pointers.
124  * Get the library version.
125  * XBSAQueryApiVersion
126  */
127 afs_int32
128 xbsa_MountLibrary(struct butx_transactionInfo *info, afs_int32 serverType)
129 {
130     void *dynlib;
131     int rc;
132
133     if (debugLevel > 98) {
134         printf("\nxbsa_MountLibraray\n");
135     }
136
137     switch (serverType) {
138     case XBSA_SERVER_TYPE_ADSM:
139 #ifndef NEW_XBSA
140 #if defined(AFS_AIX_ENV)
141         dynlib =
142             dlopen("/usr/lib/libXApi.a(bsashr10.o)",
143                    RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
144         if (dynlib == NULL) {
145             dynlib =
146                 dlopen("/usr/lib/libXApi.a(xbsa.o)",
147                        RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
148         }
149 #elif defined(AFS_SUN5_ENV)
150         dlopen ("/usr/lib/libCstd.so.1", RTLD_NOW | RTLD_GLOBAL);
151         dynlib = dlopen("/usr/lib/libXApi.so", RTLD_NOW | RTLD_GLOBAL);
152 #else
153         dynlib = NULL;
154 #endif
155 #endif
156         break;
157     default:
158         ELog(0, "xbsa_MountLibrary: The serverType %d is not recognized\n",
159              serverType);
160         return (BUTX_INVALIDSERVERTYPE);
161         break;
162     }
163
164 #ifndef NEW_XBSA
165     if (dynlib == NULL) {
166         ELog(0,
167              "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
168         return (BUTX_NOLIBRARY);
169     }
170 #endif
171
172     memset(info, 0, sizeof(struct butx_transactionInfo));
173     XBSA_SET_SERVER_TYPE(info->serverType, serverType);
174
175 #ifndef NEW_XBSA
176 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
177     XBSAInit = (BSA_Int16(*)
178                 (BSA_UInt32 *, SecurityToken *, ObjectOwner *,
179                  char **))dlsym((void *)dynlib, "BSAInit");
180     XBSABeginTxn =
181         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSABeginTxn");
182     XBSAEndTxn =
183         (BSA_Int16(*)(BSA_UInt32, Vote)) dlsym((void *)dynlib, "BSAEndTxn");
184     XBSATerminate =
185         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSATerminate");
186     XBSAQueryObject =
187         (BSA_Int16(*)(BSA_UInt32, QueryDescriptor *, ObjectDescriptor *))
188         dlsym((void *)dynlib, "BSAQueryObject");
189     XBSAGetObject =
190         (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
191         dlsym((void *)dynlib, "BSAGetObject");
192     XBSAEndData =
193         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSAEndData");
194     XBSACreateObject =
195         (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
196         dlsym((void *)dynlib, "BSACreateObject");
197     XBSAMarkObjectInactive =
198         (BSA_Int16(*)(BSA_UInt32, ObjectName *)) dlsym((void *)dynlib,
199                                                        "BSAMarkObjectInactive");
200     XBSADeleteObject =
201         (BSA_Int16(*)(BSA_UInt32, CopyType, ObjectName *, CopyId *))
202         dlsym((void *)dynlib, "BSADeleteObject");
203     XBSASendData =
204         (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
205                                                       "BSASendData");
206     XBSAGetData =
207         (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
208                                                       "BSAGetData");
209     XBSAQueryApiVersion =
210         (BSA_Int16(*)(ApiVersion *)) dlsym((void *)dynlib,
211                                            "BSAQueryApiVersion");
212     XBSAGetEnvironment =
213         (BSA_Int16(*)(BSA_UInt32, ObjectOwner *, char **))dlsym((void *)
214                                                                 dynlib,
215                                                                 "BSAGetEnvironment");
216
217     if (!XBSAInit || !XBSABeginTxn || !XBSAEndTxn || !XBSATerminate
218         || !XBSAQueryObject || !XBSAGetObject || !XBSAEndData
219         || !XBSACreateObject || !XBSADeleteObject || !XBSAMarkObjectInactive
220         || !XBSASendData || !XBSAGetData || !XBSAQueryApiVersion
221         || !XBSAGetEnvironment) {
222         ELog(0,
223              "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
224         return (BUTX_NOLIBRARY);
225     }
226     XBSAQueryApiVersion(&(info->apiVersion));
227 #endif
228 #else
229 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
230     XBSAInit                    = BSAInit;
231     XBSABeginTxn                = BSABeginTxn;
232     XBSAEndTxn                  = BSAEndTxn;
233     XBSATerminate               = BSATerminate;
234     XBSAQueryObject             = BSAQueryObject;
235     XBSAGetObject               = BSAGetObject;
236     XBSAEndData                 = BSAEndData;
237     XBSACreateObject            = BSACreateObject;
238     XBSAMarkObjectInactive      = BSAMarkObjectInactive;
239     XBSADeleteObject            = BSADeleteObject;
240     XBSASendData                = BSASendData;
241     XBSAGetData                 = BSAGetData;
242     XBSAQueryApiVersion         = BSAQueryApiVersion;
243     XBSAGetEnvironment          = BSAGetEnvironment;
244     
245     if (!XBSAInit || !XBSABeginTxn || !XBSAEndTxn || !XBSATerminate ||
246         !XBSAQueryObject || !XBSAGetObject || !XBSAEndData ||
247         !XBSACreateObject || !XBSADeleteObject || !XBSAMarkObjectInactive ||
248         !XBSASendData || !XBSAGetData || !XBSAQueryApiVersion ||
249         !XBSAGetEnvironment) {
250         ELog(0,"xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
251         return(BUTX_NOLIBRARY);
252     }
253     XBSAQueryApiVersion(&(info->apiVersion));
254 #endif
255 #endif
256
257 #ifdef DEBUG_BUTC
258         printf("xbsa_MountLibrary : XBSA function Pointers initialised. \n");
259 #endif
260     /*
261      * Verify the API version
262      */
263     if ((info->apiVersion.version == XBSA_TS_VERSION)
264         && (info->apiVersion.release == XBSA_TS_RELEASE)) {
265         /* XOPEN Techincal Standard Level! 
266          * We are coded to the Preliminary Spec!  Time to go boom!
267          */
268         ELog(0,
269              "xbsa_MountLibrary: The XBSAQueryApiVersion call returned an incompatible version, %d %d %d\n",
270              info->apiVersion.version, info->apiVersion.release,
271              info->apiVersion.level);
272         return (BUTX_INVALIDVERSION);
273     }
274
275     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
276     case XBSA_SERVER_TYPE_ADSM:
277         if ((info->apiVersion.version > XBSA_ADSM_NO_MULT_SERVER_VERSION)
278             || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
279                 && info->apiVersion.release >
280                 XBSA_ADSM_NO_MULT_SERVER_RELEASE)
281             || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
282                 && info->apiVersion.release ==
283                 XBSA_ADSM_NO_MULT_SERVER_RELEASE
284                 && info->apiVersion.level > XBSA_ADSM_NO_MULT_SERVER_LEVEL)) {
285
286             /* This version contains the fixes to allow multiple servers */
287             info->serverType |= XBSA_SERVER_FLAG_MULTIPLE;
288         } else {
289             /* This is an older version of ADSM prior to the fix to
290              * allow multiple servers.
291              */
292             info->serverType |= XBSA_SERVER_FLAG_NONE;
293         }
294         break;
295     }
296
297     return (XBSA_SUCCESS);
298
299 }
300
301 /*
302  * Set up the connection to the XBSA Server.
303  * BSAInit
304  * BSAGetEnvironment
305  */
306 afs_int32
307 xbsa_Initialize(struct butx_transactionInfo * info, char *bsaObjectOwner,
308                 char *appObjectOwner, char *secToken, char *serverName)
309 {
310     char envStrs[XBSA_NUM_ENV_STRS][BSA_MAX_DESC];
311     char *envP[XBSA_NUM_ENV_STRS + 1];
312     char *ADSMMaxObject = "TSMMAXOBJ=";
313     char *ADSMServer = "TSMSRVR=";
314     char *tempStrPtr;
315     int i;
316     int rc;
317
318     if (debugLevel > 98) {
319         printf("\nxbsa_Initialize bsaObjectOwner='%s' appObjectOwner='%s' "
320                "secToken=xxxxxx servername='%s'\n", GOODSTR(bsaObjectOwner),
321                GOODSTR(appObjectOwner), GOODSTR(serverName));
322     }
323
324     if (info->bsaHandle != 0) {
325         /* We already have a handle */
326         ELog(0,
327              "xbsa_Initialize: The dlopen call to load the XBSA shared library failed\n");
328         return (BUTX_ILLEGALINIT);
329     }
330
331     /*
332      * The XBSAGetEnvironment function is supposed to return the
333      * the serverName to use.  However, it is returning the tcpserveraddress
334      * instead.  So, we can't count on this function to properly fill it
335      * in.  So, until that get fixed.  The serverName will have to be filled
336      * in by the callers of this function (butc).
337      */
338
339     /* Initialize the environment strings */
340     for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
341         envP[i] = envStrs[i];
342     envP[XBSA_NUM_ENV_STRS] = NULL;
343
344     /* The environment variables are specific to the server type */
345     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
346     case XBSA_SERVER_TYPE_ADSM:
347         if (serverName) {
348             if (strlen(serverName) >= BSA_MAX_DESC) {
349                 ELog(0,
350                      "xbsa_Initialize: The serverName was not specified\n");
351                 return (BUTX_INVALIDSERVERNAME);
352             }
353             strcpy(info->serverName, serverName);
354             strcpy(envP[0], ADSMServer);
355             tempStrPtr = envP[0];
356             tempStrPtr = tempStrPtr + strlen(ADSMServer);
357             strcat(tempStrPtr, serverName);
358             envP[1] = NULL;
359             envP[0] = NULL;     /* Hack for TSM V5 */
360         } else {
361             envP[0] = NULL;
362             ELog(0, "xbsa_Initialize: The serverName was not specified\n");
363             return (BUTX_INVALIDSERVERNAME);
364         }
365         break;
366     default:
367         ELog(0, "xbsa_Initialize: The serverType %d is not recognized\n",
368              XBSA_GET_SERVER_TYPE(info->serverType));
369         return (BUTX_INVALIDSERVERTYPE);
370         break;
371     }
372
373     if (bsaObjectOwner) {
374         if (strlen(bsaObjectOwner) >= BSA_MAX_BSAOBJECT_OWNER) {
375             ELog(0,
376                  "xbsa_Initialize: The bsaObjectOwner is too long; size = %d; name = %s\n",
377                  strlen(bsaObjectOwner), bsaObjectOwner);
378             return (BUTX_INVALIDBSANAME);
379         }
380         strcpy(info->objOwner.bsaObjectOwner, bsaObjectOwner);
381     } else {
382         info->objOwner.bsaObjectOwner[0] = NULL;
383     }
384
385     if (appObjectOwner) {
386         if (strlen(appObjectOwner) >= BSA_MAX_APPOBJECT_OWNER) {
387             ELog(0,
388                  "xbsa_Initialize: The appObjectOwner is too long; size = %d; name = %s\n",
389                  strlen(appObjectOwner), appObjectOwner);
390             return (BUTX_INVALIDAPPNAME);
391         }
392         strcpy(info->objOwner.appObjectOwner, appObjectOwner);
393     } else {
394         info->objOwner.appObjectOwner[0] = NULL;
395     }
396
397     if (secToken) {
398         if (strlen(secToken) >= BSA_MAX_TOKEN_SIZE) {
399             ELog(0,
400                  "xbsa_Initialize: The secToken is too long; size = %d; name = %s\n",
401                  strlen(secToken), secToken);
402             return (BUTX_INVALIDSECTOKEN);
403         }
404         strcpy(info->secToken, secToken);
405     } else {
406         info->secToken[0] = NULL;
407     }
408
409     rc = (int)XBSAInit(&(info->bsaHandle), &(info->secToken),
410                        &(info->objOwner), envP);
411     if (rc != BSA_RC_SUCCESS) {
412         ELog(0, "xbsa_Initialize: The XBSAInit call failed with %d\n", rc);
413         xbsa_error(rc, info);
414         return (BUTX_INITFAIL);
415     }
416
417     /* Initialize the environment strings */
418     for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
419         envP[i] = envStrs[i];
420     envP[XBSA_NUM_ENV_STRS] = NULL;
421
422     rc = (int)XBSAGetEnvironment(info->bsaHandle, &info->objOwner, envP);
423     if (rc != BSA_RC_SUCCESS) {
424         ELog(0,
425              "xbsa_Initialize: The XBSAGetEnvironment call failed with %d\n",
426              rc);
427         xbsa_error(rc, info);
428         return (BUTX_GETENVFAIL);
429     }
430
431  info->maxObjects = 255; /* Hack for ADSM V5: unclear what this actually means... */
432
433     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
434     case XBSA_SERVER_TYPE_ADSM:
435         for (i = 0; i < XBSA_NUM_ENV_STRS; i++) {
436             if (strncmp(envP[i], ADSMMaxObject, sizeof(ADSMMaxObject)) == 0) {
437                 tempStrPtr = envP[i];
438                 tempStrPtr = tempStrPtr + strlen(ADSMMaxObject);
439                 info->maxObjects = strtol(tempStrPtr, NULL, 10);
440                 if (info->maxObjects <= 0) {
441                     ELog(0,
442                          "xbsa_Initialize: The XBSAGetEnvironment call returned an invalid value for MAXOBJ %d\n",
443                          info->maxObjects);
444                     return (BUTX_GETENVFAIL);
445                 }
446             }
447         }
448         if (info->maxObjects == 0) {
449             ELog(0,
450                  "xbsa_Initialize: The XBSAGetEnvironment call failed to return the MAXOBJ string\n");
451             return (BUTX_GETENVFAIL);
452         }
453         break;
454     }
455
456     return (XBSA_SUCCESS);
457 }
458
459 /*
460  * Create a transaction
461  * BSABeginTxn
462  */
463 afs_int32
464 xbsa_BeginTrans(struct butx_transactionInfo * info)
465 {
466     int rc;
467
468     if (debugLevel > 98) {
469         printf("\nxbsa_BeginTrans\n");
470         printf
471             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
472              GOODSTR(info->serverName),
473              GOODSTR(info->objOwner.bsaObjectOwner),
474              GOODSTR(info->objOwner.appObjectOwner));
475     }
476
477     if (info->bsaHandle == 0) {
478         /* We haven't initialized yet! */
479         ELog(0, "xbsa_BeginTrans: No current handle, butx not initialized\n");
480         return (BUTX_NOHANDLE);
481     }
482
483     rc = (int)XBSABeginTxn(info->bsaHandle);
484     if (rc != BSA_RC_SUCCESS) {
485         ELog(0, "xbsa_BeginTrans: The XBSABeginTxn call failed with %d\n",
486              rc);
487         xbsa_error(rc, info);
488         return (BUTX_BEGINTXNFAIL);
489     }
490
491     info->numObjects = 0;
492     return (XBSA_SUCCESS);
493 }
494
495 /*
496  * End the current transaction
497  * BSAEndTxn
498  */
499 afs_int32
500 xbsa_EndTrans(struct butx_transactionInfo * info)
501 {
502     int rc;
503
504     if (debugLevel > 98) {
505         printf("\nxbsa_EndTrans\n");
506         printf
507             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
508              GOODSTR(info->serverName),
509              GOODSTR(info->objOwner.bsaObjectOwner),
510              GOODSTR(info->objOwner.appObjectOwner));
511     }
512
513     if (info->bsaHandle == 0) {
514         /* We haven't initialized yet! */
515         ELog(0, "xbsa_EndTrans: No current handle, butx not initialized\n");
516         return (BUTX_NOHANDLE);
517     }
518
519     /* terminate the transaction */
520     rc = (int)XBSAEndTxn(info->bsaHandle, BSAVote_COMMIT);
521     if (rc != BSA_RC_SUCCESS) {
522         ELog(0, "xbsa_EndTrans: The XBSAEndTxn call failed with %d\n", rc);
523         xbsa_error(rc, info);
524         return (BUTX_ENDTXNFAIL);
525     }
526     return (XBSA_SUCCESS);
527 }
528
529 /*
530  * Terminate the connection to the XBSA Server.
531  * End the transaction.
532  * BSATerminate
533  */
534 afs_int32
535 xbsa_Finalize(struct butx_transactionInfo * info)
536 {
537     int rc;
538
539     if (debugLevel > 98) {
540         printf("\nxbsa_Finalize\n");
541         printf
542             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
543              GOODSTR(info->serverName),
544              GOODSTR(info->objOwner.bsaObjectOwner),
545              GOODSTR(info->objOwner.appObjectOwner));
546     }
547
548     if (info->bsaHandle == 0) {
549         /* We haven't initialized yet! */
550         ELog(0, "xbsa_Finalize: No current handle, butx not initialized\n");
551         return (BUTX_NOHANDLE);
552     }
553
554     /* terminate the session */
555     rc = (int)XBSATerminate(info->bsaHandle);
556     if (rc != BSA_RC_SUCCESS) {
557         ELog(0, "The XBSATerminate call failed with %d\n", rc);
558         xbsa_error(rc, info);
559         return (BUTX_TERMFAIL);
560     }
561
562     info->bsaHandle = 0;
563     return (XBSA_SUCCESS);
564 }
565
566 /*
567  * Query for the object we are looking for.
568  * BSAQueryObject
569  */
570 afs_int32
571 xbsa_QueryObject(struct butx_transactionInfo * info, char *objectSpaceName,
572                  char *pathName)
573 {
574     int rc;
575     QueryDescriptor queryDescriptor;
576
577     if (debugLevel > 98) {
578         printf("\nxbsa_QueryObject objectSpaceName='%s' pathnName='%s'\n",
579                GOODSTR(objectSpaceName), GOODSTR(pathName));
580         printf
581             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
582              GOODSTR(info->serverName),
583              GOODSTR(info->objOwner.bsaObjectOwner),
584              GOODSTR(info->objOwner.appObjectOwner));
585     }
586
587     if (info->bsaHandle == 0) {
588         /* We haven't initialized yet! */
589         ELog(0,
590              "xbsa_QueryObject: No current handle, butx not initialized\n");
591         return (BUTX_NOHANDLE);
592     }
593
594     /* Initialize the query for our dump name */
595
596     if (objectSpaceName) {
597         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
598             ELog(0,
599                  "xbsa_QueryObject: The objectSpaceName is too long; size = %d; name = %s\n",
600                  strlen(objectSpaceName), objectSpaceName);
601             return (BUTX_INVALIDOBJECTSPNAME);
602         }
603         strcpy(queryDescriptor.objName.objectSpaceName, objectSpaceName);
604     } else {
605         queryDescriptor.objName.objectSpaceName[0] = NULL;
606     }
607
608     if (pathName) {
609         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
610             ELog(0,
611                  "xbsa_QueryObject: The pathName is too long; size = %d; name = %s\n",
612                  strlen(pathName), pathName);
613             return (BUTX_INVALIDPATHNAME);
614         }
615         strcpy(queryDescriptor.objName.pathName, pathName);
616     } else {
617         queryDescriptor.objName.pathName[0] = NULL;
618     }
619
620     queryDescriptor.owner = info->objOwner;
621     queryDescriptor.copyType = BSACopyType_BACKUP;
622     strcpy(queryDescriptor.lGName, "");
623     strcpy(queryDescriptor.cGName, "");
624     strcpy(queryDescriptor.resourceType, "");
625     queryDescriptor.objectType = BSAObjectType_FILE;
626     queryDescriptor.status = BSAObjectStatus_ACTIVE;
627     strcpy(queryDescriptor.desc, "");
628
629     rc = (int)XBSAQueryObject(info->bsaHandle, &queryDescriptor,
630                               &info->curObject);
631     if (rc == BSA_RC_NO_MORE_DATA)
632         rc = BSA_RC_SUCCESS;    /* This is actually a success! */
633     if (rc != BSA_RC_SUCCESS) {
634         ELog(0, "xbsa_QueryObject: The xBSAQueryObject call failed with %d\n",
635              rc);
636         xbsa_error(rc, info);
637         return (BUTX_QUERYFAIL);
638     }
639     return (XBSA_SUCCESS);
640 }
641
642 /*
643  * Locate the correct object on the server and then make the call to
644  * get the object descriptor so we can begin the transfer of data.
645  * BSAGetObject
646  */
647 afs_int32
648 xbsa_ReadObjectBegin(struct butx_transactionInfo * info, char *dataBuffer,
649                      afs_int32 bufferSize, afs_int32 * count,
650                      afs_int32 * endOfData)
651 {
652     int rc;
653     DataBlock dataBlock;
654
655     if (debugLevel > 98) {
656         printf("\nxbsa_ReadObjectBegin %d Bytes\n", bufferSize);
657         printf
658             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
659              GOODSTR(info->serverName),
660              GOODSTR(info->objOwner.bsaObjectOwner),
661              GOODSTR(info->objOwner.appObjectOwner));
662     }
663
664     if (info->bsaHandle == 0) {
665         /* We haven't initialized yet! */
666         ELog(0,
667              "xbsa_ReadObjectBegin: No current handle, butx not initialized\n");
668         return (BUTX_NOHANDLE);
669     }
670
671     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
672         ELog(0, "xbsa_ReadObjectBegin: The bufferSize %d is invalid\n",
673              bufferSize);
674         return (BUTX_INVALIDBUFFERSIZE);
675     }
676
677     if (dataBuffer == NULL) {
678         ELog(0, "xbsa_ReadObjectBegin: The dataBuffer is NULL\n");
679         return (BUTX_INVALIDDATABUFFER);
680     }
681
682     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
683     dataBlock.numBytes = (BSA_UInt16) 0;
684     dataBlock.bufferPtr = dataBuffer;
685     *endOfData = 0;
686
687     rc = (int)XBSAGetObject(info->bsaHandle, &info->curObject, &dataBlock);
688     if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
689         ELog(0,
690              "xbsa_ReadObjectBegin: The XBSAGetObject call failed with %d\n",
691              rc);
692         xbsa_error(rc, info);
693         return (BUTX_GETOBJFAIL);
694     }
695     *count = dataBlock.numBytes;
696     if (rc == BSA_RC_NO_MORE_DATA)
697         *endOfData = 1;
698     return (XBSA_SUCCESS);
699 }
700
701
702 /*
703  * Tell the XBSA Server that this is the end of Data for this object.
704  * BSAEndData()
705  */
706 afs_int32
707 xbsa_ReadObjectEnd(struct butx_transactionInfo * info)
708 {
709     int rc;
710
711     if (debugLevel > 98) {
712         printf("\nxbsa_ReadObjectEnd\n");
713         printf
714             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
715              GOODSTR(info->serverName),
716              GOODSTR(info->objOwner.bsaObjectOwner),
717              GOODSTR(info->objOwner.appObjectOwner));
718     }
719
720     if (info->bsaHandle == 0) {
721         /* We haven't initialized yet! */
722         ELog(0,
723              "xbsa_ReadObjectEnd: No current handle, butx not initialized\n");
724         return (BUTX_NOHANDLE);
725     }
726     rc = (int)XBSAEndData(info->bsaHandle);
727     if (rc != BSA_RC_SUCCESS) {
728         ELog(0, "xbsa_ReadObjectEnd: XBSAEndData call failed with %d\n", rc);
729         xbsa_error(rc, info);
730         return (BUTX_ENDDATAFAIL);
731     }
732     return (XBSA_SUCCESS);
733 }
734
735
736 /*
737  * Create the XBSA Backup Copy Object.
738  * BSACreateObject
739  */
740 afs_int32
741 xbsa_WriteObjectBegin(struct butx_transactionInfo * info,
742                       char *objectSpaceName, char *pathName, char *lGName,
743                       afs_hyper_t estimatedSize, char *objectDescription,
744                       char *objectInfo)
745 {
746     int rc;
747     int length;
748     DataBlock dataBlock;
749
750     if (debugLevel > 98) {
751         printf
752             ("\nxbsa_WriteObjectBegin objectSpacename='%s' pathName='%s' lGName='%s' "
753              "estimatesSize='0x%x%08x objectDescription='%s' objectInfo='%s'\n",
754              GOODSTR(objectSpaceName), GOODSTR(pathName), GOODSTR(lGName),
755              hgethi(estimatedSize), hgetlo(estimatedSize),
756              GOODSTR(objectDescription), GOODSTR(objectInfo));
757         printf
758             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
759              GOODSTR(info->serverName),
760              GOODSTR(info->objOwner.bsaObjectOwner),
761              GOODSTR(info->objOwner.appObjectOwner));
762     }
763
764     if (info->bsaHandle == 0) {
765         /* We haven't initialized yet! */
766         ELog(0,
767              "xbsa_WriteObjectBegin: No current handle, butx not initialized\n");
768         return (BUTX_NOHANDLE);
769     }
770
771     if (objectSpaceName) {
772         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
773             ELog(0,
774                  "xbsa_WriteObjectBegin: The objectSpaceName is too long; size = %d; name = %s\n",
775                  strlen(objectSpaceName), objectSpaceName);
776             return (BUTX_INVALIDOBJECTSPNAME);
777         }
778         strcpy(info->curObject.objName.objectSpaceName, objectSpaceName);
779     } else {
780         info->curObject.objName.objectSpaceName[0] = NULL;
781     }
782
783     if (pathName) {
784         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
785             ELog(0,
786                  "xbsa_WriteObjectBegin: The pathName is too long; size = %d; name = %s\n",
787                  strlen(pathName), pathName);
788             return (BUTX_INVALIDPATHNAME);
789         }
790         strcpy(info->curObject.objName.pathName, pathName);
791     } else {
792         info->curObject.objName.pathName[0] = NULL;
793     }
794
795     if (lGName) {
796         if (strlen(lGName) >= BSA_MAX_LG_NAME) {
797             ELog(0,
798                  "xbsa_WriteObjectBegin: The lGName is too long; size = %d; name = %s\n",
799                  strlen(lGName), lGName);
800             return (BUTX_INVALIDLGNAME);
801         }
802         strcpy(info->curObject.lGName, lGName);
803     } else {
804         info->curObject.lGName[0] = NULL;
805     }
806
807     if (objectDescription) {
808         if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
809              && (strlen(objectDescription) >= ADSM_MAX_DESC))
810             ||
811             ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
812              && (strlen(objectDescription) >= BSA_MAX_DESC))) {
813             ELog(0,
814                  "xbsa_WriteObjectBegin: The objectDescription is too long; size = %d; name = %s\n",
815                  strlen(objectDescription), objectDescription);
816             return (BUTX_INVALIDOBJDESC);
817         }
818         strcpy(info->curObject.desc, objectDescription);
819     } else {
820         info->curObject.desc[0] = NULL;
821     }
822
823     if (objectInfo) {
824         if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
825              && (strlen(objectInfo) >= ADSM_MAX_OBJINFO))
826             ||
827             ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
828              && (strlen(objectInfo) >= BSA_MAX_OBJINFO))) {
829             ELog(0,
830                  "xbsa_WriteObjectBegin: The objectInfo is too long; size = %d; name = %s\n",
831                  strlen(objectInfo), objectInfo);
832             return (BUTX_INVALIDOBJINFO);
833         }
834         strcpy(info->curObject.objectInfo, objectInfo);
835     } else {
836         info->curObject.objectInfo[0] = NULL;
837     }
838
839     if (info->numObjects == info->maxObjects) {
840         /* If we've used up Max Objects we must start a new transaction. */
841         rc = (int)xbsa_EndTrans(info);
842         if (rc != XBSA_SUCCESS) {
843             return (rc);
844         }
845         rc = (int)xbsa_BeginTrans(info);
846         if (rc != XBSA_SUCCESS) {
847             return (rc);
848         }
849     }
850
851     dataBlock.bufferLen = (BSA_UInt16) 0;
852     dataBlock.numBytes = (BSA_UInt16) 0;
853     dataBlock.bufferPtr = 0;
854
855     info->curObject.Owner = info->objOwner;
856     info->curObject.copyType = BSACopyType_BACKUP;
857     info->curObject.size.left = hgethi(estimatedSize);
858     info->curObject.size.right = hgetlo(estimatedSize);
859     info->curObject.objectType = BSAObjectType_FILE;
860     strcpy(info->curObject.resourceType, resourceType);
861
862     rc = (int)XBSACreateObject(info->bsaHandle, &info->curObject, &dataBlock);
863     if (rc != BSA_RC_SUCCESS) {
864         ELog(0,
865              "xbsa_WriteObjectBegin: The XBSACreateObject call failed with %d\n",
866              rc);
867         xbsa_error(rc, info);
868         return (BUTX_CREATEOBJFAIL);
869     }
870
871     info->numObjects++;
872
873     return (XBSA_SUCCESS);
874 }
875
876 /*
877  * Delete a backup object from the server
878  * BSAMarkObjectInactive()
879  * BSADeleteObject()
880  */
881 afs_int32
882 xbsa_DeleteObject(struct butx_transactionInfo * info, char *objectSpaceName,
883                   char *pathName)
884 {
885     int rc;
886     ObjectName objectName;
887
888     if (debugLevel > 98) {
889         printf("\nxbsa_DeleteObject objectSpacename='%s' pathName='%s'\n",
890                GOODSTR(objectSpaceName), GOODSTR(pathName));
891         printf
892             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
893              GOODSTR(info->serverName),
894              GOODSTR(info->objOwner.bsaObjectOwner),
895              GOODSTR(info->objOwner.appObjectOwner));
896     }
897
898     if (info->bsaHandle == 0) {
899         /* We haven't initialized yet! */
900         ELog(0,
901              "xbsa_DeleteObject: No current handle, butx not initialized\n");
902         return (BUTX_NOHANDLE);
903     }
904
905     if (objectSpaceName) {
906         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
907             ELog(0,
908                  "xbsa_DeleteObject: The objectSpaceName is too long; size = %d; name = %s\n",
909                  strlen(objectSpaceName), objectSpaceName);
910             return (BUTX_INVALIDOBJECTSPNAME);
911         }
912         strcpy(objectName.objectSpaceName, objectSpaceName);
913     } else {
914         objectName.objectSpaceName[0] = NULL;
915     }
916
917     if (pathName) {
918         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
919             ELog(0, "xbsa_DeleteObject: strlen(pathName), pathName\n",
920                  strlen(pathName), pathName);
921             return (BUTX_INVALIDPATHNAME);
922         }
923         strcpy(objectName.pathName, pathName);
924     } else {
925         objectName.pathName[0] = NULL;
926     }
927
928     rc = (int)XBSAMarkObjectInactive(info->bsaHandle, &objectName);
929     if (rc != BSA_RC_SUCCESS) {
930         ELog(0,
931              "xbsa_DeleteObject: XBSAMarkObjectInactive call failed with %d\n",
932              rc);
933         xbsa_error(rc, info);
934         return ((rc ==
935                  BSA_RC_ABORT_ACTIVE_NOT_FOUND) ? BUTX_DELETENOVOL :
936                 BUTX_DELETEOBJFAIL);
937     }
938
939     return (XBSA_SUCCESS);
940 }
941
942 /*
943  * Tell the XBSA Server that this is the end of Data for this object.
944  * BSAEndData()
945  */
946 afs_int32
947 xbsa_WriteObjectEnd(struct butx_transactionInfo * info)
948 {
949     int rc;
950
951     if (debugLevel > 98) {
952         printf("\nxbsa_WriteObjectEnd\n");
953         printf
954             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
955              GOODSTR(info->serverName),
956              GOODSTR(info->objOwner.bsaObjectOwner),
957              GOODSTR(info->objOwner.appObjectOwner));
958     }
959
960     if (info->bsaHandle == 0) {
961         /* We haven't initialized yet! */
962         ELog(0,
963              "xbsa_WriteObjectEnd: No current handle, butx not initialized\n");
964         return (BUTX_NOHANDLE);
965     }
966     rc = (int)XBSAEndData(info->bsaHandle);
967     if (rc != BSA_RC_SUCCESS) {
968         ELog(0, "xbsa_WriteObjectEnd: XBSAEndData call failed with %d\n", rc);
969         xbsa_error(rc, info);
970         return (BUTX_ENDDATAFAIL);
971     }
972
973     return (XBSA_SUCCESS);
974 }
975
976
977 /*
978  * Write the fileset data to the XBSA server
979  * BSASendData
980  */
981 afs_int32
982 xbsa_WriteObjectData(struct butx_transactionInfo * info, char *dataBuffer,
983                      afs_int32 bufferSize, afs_int32 * count)
984 {
985     int rc;
986     DataBlock dataBlock;
987
988     if (debugLevel > 98) {
989         printf("\nxbsa_WriteObjectData %d Bytes\n", bufferSize);
990         printf
991             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
992              GOODSTR(info->serverName),
993              GOODSTR(info->objOwner.bsaObjectOwner),
994              GOODSTR(info->objOwner.appObjectOwner));
995     }
996
997     if (info->bsaHandle == 0) {
998         /* We haven't initialized yet! */
999         ELog(0,
1000              "xbsa_WriteObjectData: No current handle, butx not initialized\n");
1001         return (BUTX_NOHANDLE);
1002     }
1003
1004     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
1005         ELog(0, "xbsa_WriteObjectData: The bufferSize %d is invalid\n",
1006              bufferSize);
1007         return (BUTX_INVALIDBUFFERSIZE);
1008     }
1009
1010     if (dataBuffer == NULL) {
1011         ELog(0, "xbsa_WriteObjectData: The dataBuffer is NULL\n");
1012         return (BUTX_INVALIDDATABUFFER);
1013     }
1014
1015     dataBlock.bufferPtr = dataBuffer;
1016     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
1017     dataBlock.numBytes = (BSA_UInt16) 0;
1018
1019     rc = (int)XBSASendData(info->bsaHandle, &dataBlock);
1020     if (rc != BSA_RC_SUCCESS) {
1021         ELog(0, "xbsa_WriteObjectData: XBSAEndData call failed with %d\n",
1022              rc);
1023         xbsa_error(rc, info);
1024         return (BUTX_SENDDATAFAIL);
1025     }
1026     *count = dataBlock.numBytes;
1027     return (XBSA_SUCCESS);
1028 }
1029
1030
1031 /*
1032  * Read the fileset data from the XBSA server
1033  * BSAGetData
1034  */
1035 afs_int32
1036 xbsa_ReadObjectData(struct butx_transactionInfo * info, char *dataBuffer,
1037                     afs_int32 bufferSize, afs_int32 * count,
1038                     afs_int32 * endOfData)
1039 {
1040     int rc;
1041     DataBlock dataBlock;
1042
1043     if (debugLevel > 98) {
1044         printf("\nxbsa_ReadObjectData %d Bytes\n", bufferSize);
1045         printf
1046             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
1047              GOODSTR(info->serverName),
1048              GOODSTR(info->objOwner.bsaObjectOwner),
1049              GOODSTR(info->objOwner.appObjectOwner));
1050     }
1051
1052     if (info->bsaHandle == 0) {
1053         /* We haven't initialized yet! */
1054         ELog(0,
1055              "xbsa_ReadObjectData: No current handle, butx not initialized\n");
1056         return (BUTX_NOHANDLE);
1057     }
1058
1059     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
1060         ELog(0, "xbsa_ReadObjectData: The bufferSize %d is invalid\n",
1061              bufferSize);
1062         return (BUTX_INVALIDBUFFERSIZE);
1063     }
1064
1065     if (dataBuffer == NULL) {
1066         ELog(0, "xbsa_ReadObjectData: The dataBuffer is NULL\n");
1067         return (BUTX_INVALIDDATABUFFER);
1068     }
1069
1070     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
1071     dataBlock.numBytes = (BSA_UInt16) 0;
1072     dataBlock.bufferPtr = dataBuffer;
1073     *endOfData = 0;
1074
1075     rc = (int)XBSAGetData(info->bsaHandle, &dataBlock);
1076     if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
1077         ELog(0, "xbsa_ReadObjectData: XBSAGetData call failed with %d\n", rc);
1078         xbsa_error(rc, info);
1079         return (BUTX_GETDATAFAIL);
1080     }
1081     *count = dataBlock.numBytes;
1082     if (rc == BSA_RC_NO_MORE_DATA)
1083         *endOfData = 1;
1084     return (XBSA_SUCCESS);
1085 }
1086 #endif /*xbsa */