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