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