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