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