Always include afsconfig.h
[openafs.git] / src / butc / afsxbsa.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 #include <sys/types.h>
16 #include <afs/stds.h>
17 #include <stdio.h>
18
19
20 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
21 #include <dlfcn.h>
22 #endif
23
24 #include <errno.h>
25 #include "butc_xbsa.h"
26 #include <afs/butx.h>
27
28 /* Global Definations */
29 #define APPLTYPE "afs-butc"
30 #define TDP_LIBNAME "libApiDS.a"
31 #define FIRST_HANDLE 1
32 #define NOHANDLE 0
33 #define XAPI_FSINFO "FS for XOpen API"
34 #define DIR_DELIMITER '/'
35 #define STR_DIR_DELIMITER '/'
36
37 xGlobal xopenGbl;
38 char traceStr[DSM_MAX_RC_MSG_LENGTH+1];
39 char traceStr2[(DSM_MAX_RC_MSG_LENGTH+1) - 30];
40 char ourMsg[DSM_MAX_RC_MSG_LENGTH + 1];
41 static int dsm_init = 0 ;
42
43 /* >>>  TSM function pointers. */
44 dsInt16_t (* AFSdsmBeginQuery)( dsUint32_t dsmHandle, dsmQueryType queryType, dsmQueryBuff *queryBuffer);
45 dsInt16_t (* AFSdsmGetNextQObj)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr) ;
46 dsInt16_t (* AFSdsmEndQuery)( dsUint32_t dsmHandle);
47 dsInt16_t (* AFSdsmRCMsg)( dsUint32_t dsmHandle, dsInt16_t dsmRC, char *msg);
48 dsInt16_t (* AFSdsmLogEventEx)( dsUint32_t dsmHandle, dsmLogExIn_t *dsmLogExInP, dsmLogExOut_t *dsmLogExOutP);
49 dsInt16_t (* AFSdsmTrace)( dsUint32_t dsmHandle, char * string );
50 dsInt16_t (* AFSdsmTerminate)( dsUint32_t dsmHandle);
51 dsInt16_t (* AFSdsmSendData)( dsUint32_t dsmHandle, DataBlk *dataBlkPtri);
52 dsInt16_t (* AFSdsmBeginTxn)( dsUint32_t dsmHandle);
53 dsInt16_t (* AFSdsmDeleteObj)( dsUint32_t dsmHandle, dsmDelType delType, dsmDelInfo delInfo);
54 dsInt16_t (* AFSdsmEndTxn)( dsUint32_t dsmHandle, dsUint8_t vote, dsUint16_t *reason);
55 void (* AFSdsmQueryApiVersion)( dsmApiVersion *apiVersionP);
56 dsInt16_t (* AFSdsmInit)( dsUint32_t *dsmHandle, dsmApiVersion *dsmApiVersionP, char *clientNodeNameP, char *clientOwnerNameP, char *clientPasswordP, char *applicationType, char *configfile, char *options);
57 dsInt16_t (* AFSdsmQuerySessInfo)( dsUint32_t dsmHandle, ApiSessInfo *SessInfoP);
58 dsInt16_t (* AFSdsmBeginGetData)(dsUint32_t dsmHandle, dsBool_t mountWait, dsmGetType getType, dsmGetList *dsmGetObjListP);
59 dsInt16_t (* AFSdsmGetObj)( dsUint32_t dsmHandle, ObjID *objIdP, DataBlk *dataBlkPtr);
60 dsInt16_t (* AFSdsmEndGetObj)( dsUint32_t dsmHandle);
61 dsInt16_t (* AFSdsmEndGetData)( dsUint32_t dsmHandle);
62 dsInt16_t (* AFSdsmGetData)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr);
63 dsInt16_t (* AFSdsmEndSendObj)( dsUint32_t dsmHandle);
64 dsInt16_t (* AFSdsmRegisterFS)( dsUint32_t dsmHandle, regFSData *regFilespaceP);
65 dsInt16_t (* AFSdsmBindMC)( dsUint32_t dsmHandle, dsmObjName *objNameP, dsmSendType sendType, mcBindKey *mcBindKeyP);
66 dsInt16_t (* AFSdsmSendObj)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, DataBlk *dataBlkPtr);
67 dsInt16_t (* AFSdsmChangePW)( dsUint32_t dsmHandle, char *oldPW, char *newPW);
68 #if 0
69 dsInt16_t (* AFSdsmCleanUp)( dsBool_t mtFlag);
70 dsInt16_t (* AFSdsmDeleteAccess)( dsUint32_t dsmHandle, dsUint32_t ruleNum);
71 dsInt16_t (* AFSdsmDeleteFS)( dsUint32_t dsmHandle, char *fsName, dsUint8_t repository);
72 dsInt16_t (* AFSdsmEndGetDataEx)( dsmEndGetDataExIn_t *dsmEndGetDataExInP, dsmEndGetDataExOut_t *dsmEndGetDataExOutP);
73 dsInt16_t (* AFSdsmEndSendObjEx)( dsmEndSendObjExIn_t *dsmEndSendObjExInP, dsmEndSendObjExOut_t *dsmEndSendObjExOutP);
74 dsInt16_t (* AFSdsmEndTxnEx)( dsmEndTxnExIn_t *dsmEndTxnExInP, dsmEndTxnExOut_t *dsmEndTxnExOutP);
75 dsInt16_t (* AFSdsmGroupHandler)( dsmGroupHandlerIn_t *dsmGroupHandlerInP, dsmGroupHandlerOut_t  *dsmGroupHandlerOutP);
76 dsInt16_t (* AFSdsmInitEx)( dsUint32_t *dsmHandleP, dsmInitExIn_t *dsmInitExInP, dsmInitExOut_t *dsmInitExOutP);
77 dsInt16_t (* AFSdsmLogEvent)( dsUint32_t dsmHandle, logInfo *lopInfoP);
78 dsInt16_t (* AFSdsmQueryAccess)( dsUint32_t dsmHandle, qryRespAccessData **accessListP, dsUint16_t *numberOfRules);
79 void      (* AFSdsmQueryApiVersionEx)( dsmApiVersionEx *apiVersionP);
80 dsInt16_t (* AFSdsmQueryCliOptions)( optStruct *optstructP);
81 dsInt16_t (* AFSdsmQuerySessOptions)( dsUint32_t dsmHandle, optStruct *optstructP);
82 dsInt16_t (* AFSdsmRenameObj)( dsmRenameIn_t *dsmRenameInP, dsmRenameOut_t *dsmRenameOutP);
83 dsInt16_t (* AFSdsmSetAccess)( dsUint32_t dsmHandle, dsmAccessType accessType, dsmObjName *objNameP, char *node, char *owner);
84 dsInt16_t (* AFSdsmSetUp)( dsBool_t mtFlag, envSetUp *envSetUpPi);
85 dsInt16_t (* AFSdsmUpdateFS)( dsUint32_t dsmHandle, char *fs, dsmFSUpd *fsUpdP, dsUint32_t fsUpdAct);
86 dsInt16_t (* AFSdsmUpdateObj)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, dsUint32_t objUpdAct);
87 #endif
88 /* <<< TSM function pointers. */
89
90 typedef struct s_delList {
91   struct s_delList *next;
92   ObjID           objId;
93 } delList;
94
95 static dsInt16_t buildList(
96     dsUint32_t     dsmHandle,
97     dsmObjName     *objNameP,
98     delList        **llHeadPP,
99     delList        **llTailPP)
100 {
101    dsInt16_t            rc;
102    qryArchiveData       queryBuffer;       /* for query Archive*/
103    qryRespArchiveData   qaDataArea;
104    DataBlk              qDataBlkArea;
105    char                 descrStar[] = "*";
106    delList              *lnew = NULL, *ll = NULL;
107
108    queryBuffer.stVersion = qryArchiveDataVersion ;
109    queryBuffer.objName = objNameP;
110    queryBuffer.owner = xopenGbl.dsmSessInfo.owner;
111    queryBuffer.insDateLowerBound.year = DATE_MINUS_INFINITE;
112    queryBuffer.insDateUpperBound.year = DATE_PLUS_INFINITE;
113    queryBuffer.expDateLowerBound.year = DATE_MINUS_INFINITE;
114    queryBuffer.expDateUpperBound.year = DATE_PLUS_INFINITE;
115    queryBuffer.descr = descrStar;
116
117    if ((rc=AFSdsmBeginQuery(dsmHandle, qtArchive,
118                         (void *)&queryBuffer )) != DSM_RC_OK)
119    {
120       XOPENRETURN(dsmHandle,"buildList(AFSdsmBeginQuery)",rc,__FILE__,__LINE__);
121    }
122    qaDataArea.stVersion = qryRespArchiveDataVersion;
123    qDataBlkArea.stVersion = DataBlkVersion ;
124    qDataBlkArea.bufferPtr = (char *)&qaDataArea;
125    qDataBlkArea.bufferLen = sizeof(qryRespArchiveData);
126    while ((rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea)) == DSM_RC_MORE_DATA)
127    {
128      if (!(lnew = (delList *)dsMalloc(sizeof(delList))))
129         XOPENRETURN(dsmHandle,"buildList(AFSdsmGetNextQObj)",
130                     DSM_RC_NO_MEMORY,__FILE__,__LINE__);
131
132      if (!*llHeadPP)
133      {
134         *llHeadPP = lnew;
135         *llTailPP = lnew;
136      }
137      else
138      {
139         ll = *llTailPP;
140         ll->next = lnew;
141         *llTailPP = lnew;
142      }
143
144      lnew->next = NULL;
145      lnew->objId.hi = qaDataArea.objId.hi;
146      lnew->objId.lo = qaDataArea.objId.lo;
147    }
148
149    if (rc != DSM_RC_FINISHED)
150    {
151       AFSdsmEndQuery(dsmHandle);
152       XOPENRETURN(dsmHandle,"buildList(AFSdsmGetNextQObj)",
153                   rc,__FILE__,__LINE__);
154    }
155
156    if ((rc = AFSdsmEndQuery(dsmHandle)) != DSM_RC_OK)
157    {
158       sprintf(traceStr2, "buildList: AFSdsmEndQuery rc = %d", rc);
159       ourTrace(dsmHandle,TrFL,traceStr2);
160    }
161    XOPENRETURN(dsmHandle,"buildList",rc,__FILE__,__LINE__);
162 }
163
164 static dsInt16_t  freeList(
165     delList    **llHeadPP,
166     delList    **llTailPP)
167 {
168
169    delList *ll;
170    ll = *llHeadPP;
171    while (ll)
172    {
173       *llHeadPP = ll->next;
174       dsFree(ll);
175       ll = *llHeadPP;
176    }
177    *llHeadPP = NULL;
178    *llTailPP = NULL;
179    XOPENRETURN(0,"freeList",0,__FILE__,__LINE__);
180 }
181
182 void ourTrace(long           BSAHandle,
183               char          *fileName,
184               int            lineNumber,
185               char          *traceStr2)
186 {
187
188    sprintf(traceStr,"%s (%d) ",fileName, lineNumber);
189
190    if (traceStr2 != NULL && *traceStr2 != '\0')
191       strcat(traceStr, traceStr2);
192
193    AFSdsmTrace(BSAHandle, traceStr);
194    return;
195 }
196
197 void ourLogEvent_Ex(dsUint32_t dsmHandle, dsmLogType type, char *message,
198                     char *appMsg, dsmLogSeverity severity)
199 {
200    dsmLogExIn_t dsmLogIn;
201    dsmLogExOut_t dsmLogOut;
202    dsInt16_t    rc = 0;
203    memset(&dsmLogOut, '\0', sizeof(dsmLogExOut_t));
204
205    if (dsmHandle)
206    {
207       dsmLogIn.stVersion = dsmLogExInVersion;
208       dsmLogIn.severity = severity;
209       dsmLogIn.logType = type;
210
211       strcpy(dsmLogIn.appMsgID, appMsg);
212       dsmLogIn.message = message;
213       rc = AFSdsmLogEventEx(dsmHandle, &dsmLogIn, &dsmLogOut);
214    }
215 }
216
217 char* ourRCMsg(dsInt16_t ourRC, char *msgPrefix)
218 {
219    char         appStr[BSA_MAX_DESC];
220    char         *chP;
221    int          bytesToCp;
222
223    memset(&ourMsg, 0x00, DSM_MAX_RC_MSG_LENGTH + 1);
224    if(msgPrefix != NULL)
225    {
226        /*================================================================
227         call stdXOpenMsgMap if return code values are within the TSM
228         return code range (96 - 104). Reformat the message prefix
229         (ANS0660 - ANS0668).
230         ================================================================*/
231         if ((ourRC >= custMin_retcode) && (ourRC <= custMax_retcode))
232         {
233              stdXOpenMsgMap(ourRC, ourMsg);
234              /* set standard XOpen message prefix range: 660 - 668 */
235              ourRC = ((ourRC * 10) / 16) + (ourRC % 16) + 600;
236              sprintf(msgPrefix, "ANSO%d", ourRC);
237         }
238         else
239           /*===============================================================
240            call dsmRCMsg if return code values other then the above ranges.
241            Get message prefix from the return message of dsmRCMsg.
242            ===============================================================*/
243         {
244               AFSdsmRCMsg(NOHANDLE, ourRC, ourMsg);
245              /*=========================================================
246               search for the first ' ' and copy from beginning of string
247               until before the two charecter before ' '.
248               e.g. To get the code value from the messages of
249                    "ANS1038S Invalid option specified", we only want to
250                    get strings "ANS1038".
251               ========================================================*/
252               chP = (char *) strchr(ourMsg, ' ');
253               bytesToCp = strlen(ourMsg) - (strlen(chP) + 1);
254               strncpy(appStr, ourMsg, bytesToCp);
255               sprintf(msgPrefix, "%s", appStr);
256         }
257    }
258 return ourMsg;
259 } /* ourRCMsg() */
260
261 void StrUpper(char *s)
262 {
263    while (*s != '\0')
264    {
265       if (isalpha((int)(unsigned char)*s))
266          *s = (char)toupper((int)(unsigned char)*s);
267       s++;
268
269    } /* end while */
270 } /* StrUpper() */
271
272 BSA_Int16 xparsePath(
273     long           BSAHandle,
274     char          *pathname,
275     char          *hl,
276     char          *ll)
277 {
278    /*=== code taken from dscparse.c ParseDestOperand function ===*/
279
280    dsInt16_t    opLen;
281    dsInt16_t    x;
282
283    *hl = *ll = '\0';
284
285    strcpy(hl, pathname);   /* use hl as working area */
286    if ((opLen = strlen(hl)) > 0)
287    {
288       /*=== Find the ll portion of the name ===*/
289       #ifdef MBCS
290       {
291          char *llstart;
292          llstart = strrchr(hl,DIR_DELIMITER);
293          if (llstart == NULL)
294             x = 0;
295          else
296             x = llstart - hl;
297       }
298       #else
299          for (x = opLen-1; x>0 && hl[x]!=DIR_DELIMITER; x--);
300       #endif
301
302          /*=== If there is no leading delimiter then add one ===*/
303          if (hl[x] != DIR_DELIMITER)
304             strcpy(ll, STR_DIR_DELIMITER);
305
306          strncat(ll, hl+x, opLen-x);
307
308          hl[x] = '\0';          /* Shorten hl by length of ll */
309    }
310    return 0;
311 }
312
313 BSA_Int16 xlateRC(
314     long           BSAHandle,
315     BSA_Int16      dsmRC,
316     BSA_Int16      *bsaRCP)
317
318 {
319    switch (dsmRC)
320    {
321       case DSM_RC_OK:
322          *bsaRCP=BSA_RC_OK;                              break;
323
324       case DSM_RC_ABORT_ACTIVE_NOT_FOUND:
325          *bsaRCP=BSA_RC_ABORT_ACTIVE_NOT_FOUND;          break;
326
327       case DSM_RC_ABORT_SYSTEM_ERROR:
328          *bsaRCP=BSA_RC_ABORT_SYSTEM_ERROR;              break;
329
330       case DSM_RC_ABORT_BAD_VERIFIER:
331       case DSM_RC_AUTH_FAILURE:
332       case DSM_RC_REJECT_ID_UNKNOWN:
333       case DSM_RC_REJECT_DUPLICATE_ID:
334          *bsaRCP=BSA_RC_AUTHENTICATION_FAILURE;          break;
335
336       case DSM_RC_BAD_CALL_SEQUENCE:
337          *bsaRCP=BSA_RC_BAD_CALL_SEQUENCE;               break;
338
339       case DSM_RC_INVALID_DS_HANDLE:
340          *bsaRCP=BSA_RC_BAD_HANDLE;                      break;
341
342       case DSM_RC_BUFF_TOO_SMALL:
343          *bsaRCP=BSA_RC_BUFFER_TOO_SMALL;                break;
344
345       case DSM_RC_DESC_TOOLONG:
346          *bsaRCP=BSA_RC_DESC_TOO_LONG;                   break;
347
348       case DSM_RC_FILESPACE_TOOLONG:
349          *bsaRCP=BSA_RC_OBJECTSPACE_TOO_LONG;            break;
350
351       /* some other condition here ? */
352       case DSM_RC_PASSWD_TOOLONG:
353          *bsaRCP=BSA_RC_INVALID_TOKEN;                   break;
354
355       case DSM_RC_INVALID_VOTE:
356          *bsaRCP=BSA_RC_INVALID_VOTE;                    break;
357
358       case DSM_RC_INVALID_OPT:
359          *bsaRCP=BSA_RC_INVALID_KEYWORD;                 break;
360
361       /*  ? what conditions cause this - object already exists ?
362       case DSM_RC_?:
363          *bsaRCP=BSA_RC_MATCH_EXISTS;                    break;
364       */
365
366       case DSM_RC_MORE_DATA:
367          *bsaRCP=BSA_RC_MORE_DATA;                       break;
368
369       /* not supported - for QueryAccessRule
370       case :
371          *bsaRCP=BSA_RC_MORE_RULES;                      break;
372       */
373
374       case DSM_RC_NEWPW_REQD:
375          *bsaRCP=BSA_RC_NEWTOKEN_REQD;                   break;
376
377       case DSM_RC_ABORT_NO_MATCH:
378       case DSM_RC_FILE_SPACE_NOT_FOUND:
379       /*=== rc for query ===*/
380          *bsaRCP=BSA_RC_NO_MATCH;                        break;
381       /*=== if this return code comes on Delete, use OBJECT_NOT_FOUND
382             - see xopndel.c ===*/
383
384       case DSM_RC_FINISHED:
385          *bsaRCP=BSA_RC_NO_MORE_DATA;                    break;
386
387       case DSM_RC_ABORT_NO_LOG_SPACE:
388       case DSM_RC_ABORT_NO_DB_SPACE:
389       case DSM_RC_ABORT_NO_MEMORY:
390       case DSM_RC_ABORT_NO_REPOSIT_SPACE:
391       case DSM_RC_REJECT_NO_RESOURCES:
392       case DSM_RC_REJECT_NO_MEMORY:
393       case DSM_RC_REJECT_NO_DB_SPACE:
394       case DSM_RC_REJECT_NO_LOG_SPACE:
395          *bsaRCP=BSA_RC_NO_RESOURCES;                    break;
396
397       case DSM_RC_NULL_DATABLKPTR:
398          *bsaRCP=BSA_RC_NULL_DATABLKPTR;                 break;
399
400       case DSM_RC_NULL_OBJNAME:
401          *bsaRCP=BSA_RC_NULL_OBJNAME;                    break;
402
403       case DSM_RC_NULL_BUFPTR:
404          *bsaRCP=BSA_RC_NULL_POINTER;                    break;
405
406       /* not supported - for DeleteAccessRule
407       case :
408          *bsaRCP=BSA_RC_NULL_RULEID;                     break;
409       */
410
411       case DSM_RC_HL_TOOLONG:
412       case DSM_RC_LL_TOOLONG:
413          *bsaRCP=BSA_RC_OBJECT_NAME_TOO_LONG;            break;
414
415       /* not supported - for DeletePolicyDomain
416       case :
417          *bsaRCP=BSA_RC_OBJECT_NOT_EMPTY;                break;
418       */
419
420       /* same as NO_MATCH for DeleteObject
421       case :
422          *bsaRCP=BSA_RC_OBJECT_NOT_FOUND;                break;
423       */
424
425       case DSM_RC_OBJINFO_TOOLONG:
426          *bsaRCP=BSA_RC_OBJINFO_TOO_LONG;                break;
427
428       /* same as BSA_RC_OBJECT_NAME_TOO_LONG
429       case :
430          *bsaRCP=BSA_RC_OBJNAME_TOO_LONG;                break;
431       */
432
433       /* not supported - for CreatePolicySet, etc
434       case :
435          *bsaRCP=BSA_RC_OPERATION_NOT_AUTHORIZED;        break;
436       */
437
438       case DSM_RC_OLDPW_REQD:
439          *bsaRCP=BSA_RC_OLDTOKEN_REQD;                   break;
440
441       case DSM_RC_REJECT_VERIFIER_EXPIRED:
442          *bsaRCP=BSA_RC_TOKEN_EXPIRED;                   break;
443
444       case DSM_RC_WILL_ABORT:
445       case DSM_RC_CHECK_REASON_CODE:
446          *bsaRCP=BSA_RC_TXN_ABORTED;                     break;
447
448       case DSM_RC_UNMATCHED_QUOTE:
449          *bsaRCP=BSA_RC_UNMATCHED_QUOTE;                 break;
450
451       /* not supported - for DeleteUser
452       case :
453          *bsaRCP=BSA_RC_USER_OWNS_OBJECT;                break;
454       */
455
456       default:
457       {
458          /*=========================================================
459           No suitable match, so print message in log, if we still
460           have a handle.  AFSdsmInit calls ApiCleanUp in certain error
461           situations.  We lose the handle in those cases so check
462           for it.
463           =========================================================*/
464
465          char         rcMsg[DSM_MAX_RC_MSG_LENGTH] ;
466          char         errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
467          char         ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
468          dsUint32_t   dsmHandle;
469
470          memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
471          memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
472
473          if (BSAHandle)
474          {
475             dsmHandle = BSAHandle;
476             AFSdsmRCMsg(dsmHandle,dsmRC,rcMsg) ;
477             strcat(rcMsg, "\n");
478             sprintf(traceStr2,
479                    "xlateRC - %s", rcMsg);
480             ourTrace(BSAHandle,TrFL, traceStr2);
481             strcpy(ourMessage, ourRCMsg(dsmRC, errPrefix));
482             ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
483          }
484
485          *bsaRCP = ADSM_RC_ERROR;
486       }
487    }
488
489    /*=== trace only if we have a valid handle ===*/
490    if (dsmRC && BSAHandle)
491    {
492       sprintf(traceStr2, "xlateRC: TSM rc >%d< , BSA rc >%d<", dsmRC, *bsaRCP);
493       ourTrace(BSAHandle, TrFL, traceStr2);
494    }
495    return DSM_RC_OK ;
496 }
497
498 void stdXOpenMsgMap(dsInt16_t  rc,  char *msg)
499 {
500    switch(rc)
501    {
502       case ADSM_RC_ERROR:
503            strcpy(msg, "TSM rc error, see ADSM error log.");
504       case ADSM_RC_INVALID_NODE:
505            strcpy(msg, "BSAObjectOwner doesn't match value session Init.");
506            break;
507
508       case ADSM_RC_INVALID_COPYTYPE:
509            strcpy(msg, "Invalid copy type.");
510            break;
511
512       case ADSM_RC_INVALID_OBJTYPE:
513            strcpy(msg, "Invalid object type.");
514            break;
515
516       case ADSM_RC_INVALID_STATUS:
517            strcpy(msg, "Invalid Object Status.");
518            break;
519
520       case ADSM_RC_INVALID_ST_VER:
521            strcpy(msg, "Invalid object descriptor structure version.");
522            break;
523
524       case ADSM_RC_OWNER_TOO_LONG:
525            strcpy(msg, "Object owner name too long.");
526            break;
527
528       case ADSM_RC_PSWD_TOO_LONG:
529            strcpy(msg, "Client password too long.");
530            break;
531
532      case ADSM_RC_PSWD_GEN:
533           strcpy(msg, "Password input required .");
534           break;
535
536      default:
537            strcpy(msg, "No message available");
538            break;
539    }
540 }
541
542 BSA_Int16 fillArchiveResp(
543 long                BSAHandle,
544 ObjectDescriptor   *BSAobjDescP,
545 qryRespArchiveData *respArchiveP
546 )
547 {
548    XAPIObjInfo   *xapiObjInfoP;
549
550    strcpy(BSAobjDescP->Owner.appObjectOwner, respArchiveP->owner);
551    strcpy(BSAobjDescP->objName.objectSpaceName, respArchiveP->objName.fs);
552
553    /*=== concatenate hl and ll for pathName ===*/
554    strcpy(BSAobjDescP->objName.pathName, respArchiveP->objName.hl);
555    strcat(BSAobjDescP->objName.pathName, respArchiveP->objName.ll);
556
557    BSAobjDescP->createTime.tm_year = respArchiveP->insDate.year-1900;
558    BSAobjDescP->createTime.tm_mon  = respArchiveP->insDate.month-1;
559    BSAobjDescP->createTime.tm_mday = respArchiveP->insDate.day  ;
560    BSAobjDescP->createTime.tm_hour = respArchiveP->insDate.hour ;
561    BSAobjDescP->createTime.tm_min  = respArchiveP->insDate.minute ;
562    BSAobjDescP->createTime.tm_sec  = respArchiveP->insDate.second ;
563
564    BSAobjDescP->copyId.left  = respArchiveP->objId.hi;
565    BSAobjDescP->copyId.right = respArchiveP->objId.lo;
566
567    BSAobjDescP->restoreOrder.left  = respArchiveP->restoreOrderExt.lo_hi;
568    BSAobjDescP->restoreOrder.right = respArchiveP->restoreOrderExt.lo_lo;
569
570    strcpy(BSAobjDescP->lGName, respArchiveP->mcName) ;
571
572    xapiObjInfoP = (XAPIObjInfo *)&(respArchiveP->objInfo);
573    BSAobjDescP->size.left = xapiObjInfoP->size.left;
574    BSAobjDescP->size.right= xapiObjInfoP->size.right;
575    strcpy(BSAobjDescP->resourceType, xapiObjInfoP->resourceType);
576    strcpy(BSAobjDescP->desc, xapiObjInfoP->partDesc);
577    strcpy(BSAobjDescP->objectInfo, xapiObjInfoP->partObjInfo);
578
579    if (respArchiveP->objName.objType == DSM_OBJ_DIRECTORY)
580       BSAobjDescP->objectType = BSAObjectType_DIRECTORY;
581    else
582       BSAobjDescP->objectType = BSAObjectType_FILE;
583       /*=== future - type DATABASE ?? ===*/
584
585       BSAobjDescP->status = BSAObjectStatus_ACTIVE;
586       XOPENRETURN(BSAHandle, "fillArchiveResp",
587                   BSA_RC_SUCCESS,__FILE__,__LINE__);
588 }
589
590 BSA_Int16 fillBackupResp(
591 long               BSAHandle,
592 ObjectDescriptor  *BSAobjDescP,
593 qryRespBackupData *respBackupP
594 )
595 {
596    XAPIObjInfo   *xapiObjInfoP;
597
598    strcpy(BSAobjDescP->Owner.appObjectOwner, respBackupP->owner);
599    strcpy(BSAobjDescP->objName.objectSpaceName, respBackupP->objName.fs);
600
601    /*=== concatenate hl and ll for pathName ===*/
602    strcpy(BSAobjDescP->objName.pathName, respBackupP->objName.hl);
603    strcat(BSAobjDescP->objName.pathName, respBackupP->objName.ll);
604
605    BSAobjDescP->createTime.tm_year = respBackupP->insDate.year-1900;
606    BSAobjDescP->createTime.tm_mon  = respBackupP->insDate.month-1;
607    BSAobjDescP->createTime.tm_mday = respBackupP->insDate.day  ;
608    BSAobjDescP->createTime.tm_hour = respBackupP->insDate.hour ;
609    BSAobjDescP->createTime.tm_min  = respBackupP->insDate.minute ;
610    BSAobjDescP->createTime.tm_sec  = respBackupP->insDate.second ;
611
612    BSAobjDescP->copyId.left  = respBackupP->objId.hi;
613    BSAobjDescP->copyId.right = respBackupP->objId.lo;
614
615    BSAobjDescP->restoreOrder.left  = respBackupP->restoreOrderExt.lo_hi;
616    BSAobjDescP->restoreOrder.right = respBackupP->restoreOrderExt.lo_lo;
617
618    strcpy(BSAobjDescP->lGName, respBackupP->mcName) ;
619
620    xapiObjInfoP = (XAPIObjInfo *)&(respBackupP->objInfo);
621    BSAobjDescP->size.left = xapiObjInfoP->size.left;
622    BSAobjDescP->size.right= xapiObjInfoP->size.right;
623    strcpy(BSAobjDescP->resourceType, xapiObjInfoP->resourceType);
624    strcpy(BSAobjDescP->desc, xapiObjInfoP->partDesc);
625    strcpy(BSAobjDescP->objectInfo, xapiObjInfoP->partObjInfo);
626
627    if (respBackupP->objName.objType == DSM_OBJ_DIRECTORY)
628       BSAobjDescP->objectType = BSAObjectType_DIRECTORY;
629    else
630       BSAobjDescP->objectType = BSAObjectType_FILE;
631       /*=== future - type DATABASE ?? ===*/
632
633    if (respBackupP->objState == DSM_ACTIVE)
634       BSAobjDescP->status = BSAObjectStatus_ACTIVE;
635    else
636       BSAobjDescP->status = BSAObjectStatus_INACTIVE;
637       /*=== ?? check for any other ===*/
638
639    XOPENRETURN(BSAHandle, "fillRBackupResp",
640                BSA_RC_SUCCESS,__FILE__,__LINE__);
641 }
642
643
644 afs_int32 dsm_MountLibrary()
645 {
646 void * dynlib = NULL ;
647
648 #ifdef DEBUG_BUTC
649     printf("dsm_MountLibrary : inside function.  \n");
650 #endif
651 #if defined(AFS_AIX_ENV)
652         dynlib = dlopen("/usr/lib/libApiDS.a(dsmapish.o)", RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
653 #elif defined (AFS_AMD64_LINUX26_ENV)
654         dynlib = dlopen("/usr/lib64/libApiTSM64.so", RTLD_NOW | RTLD_LOCAL);
655 #elif defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
656         dynlib = dlopen("/usr/lib/libApiDS.so", RTLD_NOW | RTLD_LOCAL);
657 #else
658         dynlib = NULL;
659 #endif
660
661         if (dynlib == NULL) {
662                 ELog(0,"dsm_MountLibrary: The dlopen call to load the libApiDS shared library failed\n");
663                 return(BUTX_NOLIBRARY);
664         }
665
666 #ifdef DEBUG_BUTC
667         printf("dsm_MountLibrary : SUCCESS to Open the libApiDS shared library. \n");
668 #endif
669 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
670         AFSdsmBeginQuery = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmQueryType queryType, dsmQueryBuff *queryBuffer)) dlsym((void *)dynlib, "dsmBeginQuery"); 
671         AFSdsmGetNextQObj = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetNextQObj") ;
672         AFSdsmEndQuery = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndQuery");
673         AFSdsmRCMsg = (dsInt16_t (*)( dsUint32_t dsmHandle, dsInt16_t dsmRC, char *msg))dlsym((void *)dynlib, "dsmRCMsg");
674         AFSdsmLogEventEx = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmLogExIn_t *dsmLogExInP, dsmLogExOut_t *dsmLogExOutP))dlsym((void *)dynlib, "dsmLogEventEx");
675         AFSdsmTrace = (dsInt16_t (*)( dsUint32_t dsmHandle, char * string ))dlsym((void *)dynlib, "dsmTrace");
676         AFSdsmTerminate = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmTerminate");
677         AFSdsmSendData = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtri))dlsym((void *)dynlib, "dsmSendData");
678         AFSdsmBeginTxn = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmBeginTxn");
679         AFSdsmDeleteObj = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmDelType delType, dsmDelInfo delInfo))dlsym((void *)dynlib, "dsmDeleteObj");
680         AFSdsmEndTxn = (dsInt16_t (*)( dsUint32_t dsmHandle, dsUint8_t vote, dsUint16_t *reason))dlsym((void *)dynlib, "dsmEndTxn");
681         AFSdsmQueryApiVersion = (void (*)( dsmApiVersion *apiVersionP))dlsym((void *)dynlib, "dsmQueryApiVersion");
682         AFSdsmInit = (dsInt16_t (*)( dsUint32_t *dsmHandle, dsmApiVersion *dsmApiVersionP, char *clientNodeNameP, char *clientOwnerNameP, char *clientPasswordP, char *applicationType, char *configfile, char *options))dlsym((void *)dynlib, "dsmInit");
683         AFSdsmQuerySessInfo = (dsInt16_t (*)( dsUint32_t dsmHandle, ApiSessInfo *SessInfoP))dlsym((void *)dynlib, "dsmQuerySessInfo");
684         AFSdsmBeginGetData = (dsInt16_t (*)(dsUint32_t dsmHandle, dsBool_t mountWait, dsmGetType getType, dsmGetList *dsmGetObjListP))dlsym((void *)dynlib, "dsmBeginGetData");
685         AFSdsmGetObj = (dsInt16_t (*)( dsUint32_t dsmHandle, ObjID *objIdP, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetObj");
686         AFSdsmEndGetObj = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndGetObj");
687         AFSdsmEndGetData = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndGetData");
688         AFSdsmGetData = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetData");
689         AFSdsmEndSendObj = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndSendObj");
690         AFSdsmRegisterFS = (dsInt16_t (*)( dsUint32_t dsmHandle, regFSData *regFilespaceP))dlsym((void *)dynlib, "dsmRegisterFS");
691         AFSdsmBindMC = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmObjName *objNameP, dsmSendType sendType, mcBindKey *mcBindKeyP))dlsym((void *)dynlib, "dsmBindMC");
692         AFSdsmSendObj = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmSendObj");
693         AFSdsmChangePW = (dsInt16_t (*)( dsUint32_t dsmHandle, char *oldPW, char *newPW))dlsym((void *)dynlib, "dsmChangePW");
694
695
696         if (    !AFSdsmBeginQuery || !AFSdsmGetNextQObj || !AFSdsmEndQuery ||
697                 !AFSdsmRCMsg || !AFSdsmLogEventEx || !AFSdsmTrace || 
698                 !AFSdsmTerminate || !AFSdsmEndGetObj || !AFSdsmSendData || 
699                 !AFSdsmBeginTxn || !AFSdsmDeleteObj || !AFSdsmEndGetData ||
700                 !AFSdsmEndTxn || !AFSdsmQueryApiVersion || !AFSdsmInit || 
701                 !AFSdsmGetData || !AFSdsmQuerySessInfo || !AFSdsmBeginGetData ||
702                 !AFSdsmGetObj || !AFSdsmEndSendObj || !AFSdsmRegisterFS || 
703                 !AFSdsmBindMC || !AFSdsmSendObj || !AFSdsmChangePW ) 
704         {
705                 ELog(0,"dsm_MountLibrary: The dlopen call to load the TSM shared library failed\n");
706                 return(BUTX_NOLIBRARY);
707         }
708 #ifdef DEBUG_BUTC
709                 printf("dsm_MountLibrary : All TSM function pointers initialized. \n");
710 #endif
711
712 #endif
713         dsm_init = 1 ;
714 #ifdef DEBUG_BUTC
715     printf("dsm_MountLibrary : leaving function. \n");
716 #endif
717         return 0 ;
718
719 }
720
721 BSA_Int16 BSAInit( long     *BSAHandleP,
722                    SecurityToken  *clientPasswordP,
723                    ObjectOwner    *objectOwnerP,
724                    char          **envP )
725 {
726    dsInt16_t        rc = 0;
727    dsInt16_t        saverc = 0;
728    BSA_Int16        bsaRC = 0;
729    dsUint32_t       dsmHandle;   /* use diff field when talking to base
730                                    code in case either format changes */
731    dsmApiVersion    xapiHdrVer;  /* Xopen API build version           */
732    dsmApiVersion    apiLibVer;  /* Xopen API Libary version          */
733
734    dsUint32_t       xapiVersion, apiVersion;
735    envSetUp         dsmEnvSetUp;
736
737    /*==================================================================
738      Today the BSA constants have the same values as the DSM constants.
739      If this changes, use strncpy.
740      =================================================================*/
741
742    char            rcmsg[DSM_MAX_RC_MSG_LENGTH + 1];
743    char            dsmNode[DSM_MAX_NODE_LENGTH];
744    char            dsmOwner[DSM_MAX_OWNER_LENGTH];
745    char            dsmPswd[DSM_MAX_VERIFIER_LENGTH];
746    char           *dsmNodeP;
747    char           *dsmOwnerP;
748    char           *dsmPswdP;
749    char            options[DSM_MAX_RC_MSG_LENGTH];
750    char           *optionP = NULL;
751    char            TDPLibName[BSA_MAX_DESC];
752    char            TDPILibName[BSA_MAX_DESC];
753    int             i=0;
754    char            errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
755    char            ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
756    char            rcMsg[DSM_MAX_RC_MSG_LENGTH + 1];
757
758    dsmHandle = 0;
759   *BSAHandleP = 0;
760
761 #ifdef DEBUG_BUTC
762    printf("BSAInit : inside function. \n");
763 #endif
764    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
765    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
766    memset(rcMsg,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
767
768    if(!dsm_init)
769    {
770 #ifdef DEBUG_BUTC
771         printf("TSM library not mounted. \n");
772 #endif
773         if (dsm_MountLibrary())
774         {
775                 printf("TSM Library initialisation failed. \n");
776                 return 1 ;
777         }
778 #ifdef DEBUG_BUTC
779         printf("TSM Library initialisation SUCCESS. \n");
780 #endif
781    }
782
783    /*==================================================================
784     Trace won't work before AFSdsmInit, moved to after call to AFSdsmInit
785     The XOpen library is built by statically linking with the API and
786     client common modules.  So, the version checking is unnecessary.
787     We'll fill in the value anyway for consistency.
788     ==================================================================*/
789    memset(&xapiHdrVer,0x00,sizeof(dsmApiVersion));
790    memset(&apiLibVer,0x00,sizeof(dsmApiVersion));
791    memset(&dsmEnvSetUp,0x00,sizeof(envSetUp));
792
793    AFSdsmQueryApiVersion(&apiLibVer);
794
795    xapiHdrVer.version = DSM_API_VERSION;  /* Set the applications    */
796    xapiHdrVer.release = DSM_API_RELEASE;  /* compile time version.   */
797    xapiHdrVer.level   = DSM_API_LEVEL;    /* version                 */
798
799    xapiVersion = (1000 * DSM_API_VERSION) + (100 * DSM_API_RELEASE)
800                   + DSM_API_LEVEL;
801
802    apiVersion  = (1000 * apiLibVer.version) + (100 * apiLibVer.release)
803                   + apiLibVer.level;
804
805    /* check for compatibility problems */
806    if (apiVersion < xapiVersion)
807         return ADSM_RC_ERROR;
808
809    /*==== Init global area ===*/
810
811    memset(&xopenGbl,0x00, sizeof(xGlobal));  /* Zero out block.        */
812
813    memset(dsmNode,0x00,DSM_MAX_NODE_LENGTH);
814    memset(dsmOwner,0x00,DSM_MAX_OWNER_LENGTH);
815    memset(dsmPswd,0x00,DSM_MAX_VERIFIER_LENGTH);
816    memset(options,0x00,DSM_MAX_RC_MSG_LENGTH);
817    memset(TDPLibName,0x00,BSA_MAX_DESC);
818    memset(TDPILibName,0x00,BSA_MAX_DESC);
819
820    memset(rcmsg,         '\0', DSM_MAX_RC_MSG_LENGTH + 1);
821
822
823    /*=== Validate the inputs ===*/
824
825    if (objectOwnerP)
826    {
827       if (strlen(objectOwnerP->bsaObjectOwner) > BSA_MAX_BSAOBJECT_OWNER)
828       {
829          bsaRC = ADSM_RC_OWNER_TOO_LONG;
830          return(bsaRC);
831       }
832
833       if (strlen(objectOwnerP->appObjectOwner) > BSA_MAX_APPOBJECT_OWNER)
834       {
835          bsaRC = ADSM_RC_OWNER_TOO_LONG;
836          return(bsaRC);
837       }
838
839       if (objectOwnerP->bsaObjectOwner[0] == '\0') /* empty string */
840          dsmNodeP = NULL;
841       else
842       {
843          strcpy(dsmNode, objectOwnerP->bsaObjectOwner);
844          dsmNodeP = dsmNode;
845       }
846
847       if (objectOwnerP->appObjectOwner[0] == '\0') /* empty string  */
848          dsmOwnerP = NULL;
849       else
850       {
851          strcpy(dsmOwner, objectOwnerP->appObjectOwner);
852          dsmOwnerP = dsmOwner;
853       }
854    }
855    else
856    {
857       dsmNodeP = NULL;
858       dsmOwnerP = NULL;
859    }
860
861    if (clientPasswordP != NULL)
862    {
863       if (strlen((const char *)clientPasswordP) > BSA_MAX_TOKEN_SIZE)
864       {
865          bsaRC = ADSM_RC_PSWD_TOO_LONG;
866          return(bsaRC);
867       }
868
869       strcpy(dsmPswd, (const char *)clientPasswordP);
870       dsmPswdP = dsmPswd;
871    }
872    else
873       dsmPswdP = NULL;
874       {
875           while ((envP[i] != NULL) && (envP[i] != '\0'))
876           {
877              strcat(options, "-");
878              strcat(options, envP[i]);
879              if ((envP[i+1] != NULL) && (envP[i+1] != '\0'))
880                 strcat(options, " ");
881                 i++;
882           }
883
884           if (options[0] == '\0')   /* empty string */
885              optionP = NULL;
886           else
887              optionP = options;
888
889           rc = AFSdsmInit(&dsmHandle,   /* On return contains session handle.   */
890                        &xapiHdrVer,   /* Version of the API we are using.     */
891                        dsmNodeP,      /* node name                            */
892                        dsmOwnerP,     /* owner name                           */
893                        dsmPswdP,      /* password                             */
894                        APPLTYPE,      /* Name of our node type.               */
895                        NULL,          /* no API config file name              */
896                        optionP);      /* option string                        */
897      }
898
899      if (rc == DSM_RC_OK)
900      {
901         /*=== now that AFSdsmInit issued, we can trace ===*/
902         sprintf(traceStr2,
903                 "BSAInit: original bsaOwner=%s, appOwner=%s, token=%s, Appl Type=%s, options=%s.",
904                  dsmNode, dsmOwner, dsmPswd, APPLTYPE, options);
905         ourTrace(dsmHandle, TrFL, traceStr2);
906         {
907               strcpy(TDPLibName, TDP_LIBNAME);
908               sprintf(traceStr2,
909                      "BSAInit: Using TSM Native API library : %s", TDPLibName);
910               ourTrace(dsmHandle, TrFL, traceStr2);
911         }
912      }
913
914
915      /*=================================================================
916      If the password expired, continue initialization so the session
917      can continue.
918
919      Save the 'password expired' rc away, so we can return it to the
920      caller.
921
922      The application will be responsible for issuing a BSAChangeToken()
923      to update the password.
924      =================================================================*/
925      if (rc == DSM_RC_REJECT_VERIFIER_EXPIRED)
926      {
927         /*=== don't return yet - init global so session can continue ===*/
928
929          saverc = rc;
930          rc = DSM_RC_OK;
931      }
932      else
933         if ((rc == DSM_RC_NO_OWNER_REQD) ||
934             (rc == DSM_RC_NO_NODE_REQD))       /* pswd=generate */
935         {
936             AFSdsmTerminate(dsmHandle);
937             bsaRC = ADSM_RC_PSWD_GEN;
938             return (bsaRC);
939         }
940
941
942    /*==================================================================
943      If we ran into any problems so far, rc will be non-zero or 'true'.
944
945      This is not true for password expired, since we reset rc to zero
946      in that case.  We'll have to check for that later so we return
947      the 'password expired' indication to the caller.
948      ==================================================================*/
949
950    if (rc)
951    {
952       AFSdsmRCMsg(dsmHandle, rc, rcmsg);
953       sprintf(traceStr2, "BSAInit(AFSdsmInit): Messages - %s ", rcmsg);
954       ourTrace(dsmHandle, TrFL, traceStr2);
955       strcpy(ourMessage, ourRCMsg(rc, errPrefix));
956       ourLogEvent_Ex(dsmHandle, logLocal, ourMessage, errPrefix, logSevError);
957       xlateRC(*BSAHandleP, rc, &bsaRC); /* BSAHandle still 0, but not used */
958       AFSdsmTerminate(dsmHandle);          /* clean up memory blocks          */
959       return (bsaRC);
960    }
961
962
963    {
964       char msg[256];                    /* format string and watch for NULLs */
965
966       strcpy(msg, "BSAInit for node=");
967
968       if (objectOwnerP)
969       {
970          if (dsmNodeP)
971             strcat(msg, dsmNodeP);
972          else
973             strcat(msg, "<empty>");
974       }
975       else
976          strcat(msg, "<NULL>");
977
978       strcat(msg, ", owner=");
979
980       if (objectOwnerP)
981       {
982          if (dsmOwnerP)
983             strcat(msg, dsmOwnerP);
984          else
985             strcat(msg, "<empty>");
986       }
987       else
988          strcat(msg, "<NULL>");
989
990       strcat(msg, ".\n");
991
992       sprintf(traceStr, msg);
993    }
994
995    *BSAHandleP = (long)dsmHandle;
996
997
998    /*=================================================================
999     For password expired processing the application is responsible for
1000     issuing BSAChangeToken() to update the password, when they see the
1001     'expired password' return code.
1002
1003     The BSAChangeToken() command will issue the AFSdsmQuerySessInfo()
1004     call, so don't issue it here.
1005     =================================================================*/
1006
1007    if (!saverc)               /* don't call this if we got pswd expire */
1008    {
1009       /*=== now query session info to populate the global structure ===*/
1010
1011       xopenGbl.dsmSessInfo.stVersion = ApiSessInfoVersion;
1012       rc = AFSdsmQuerySessInfo(dsmHandle,                /* Session handle */
1013                             &xopenGbl.dsmSessInfo);   /* Output struct  */
1014
1015       if (rc)
1016       {
1017          sprintf(traceStr2, "BSAInit(AFSdsmQuerySessInfo): error rc = %d", rc);
1018          ourTrace(dsmHandle, TrFL, traceStr2);
1019          AFSdsmTerminate(dsmHandle);
1020          *BSAHandleP = 0;
1021       }
1022       else
1023       {
1024          sprintf(traceStr2, "BSAInit: Actual node=%s, actual DSM owner=%s, servername=%s.",
1025                  xopenGbl.dsmSessInfo.id, xopenGbl.dsmSessInfo.owner,
1026                  xopenGbl.dsmSessInfo.adsmServerName);
1027          ourTrace(dsmHandle, TrFL, traceStr2);
1028       }
1029    }
1030    else
1031    {
1032       /*============================================================
1033         Indicate in the session flags that we encountered a password
1034         expiration condition.  The application will know that this
1035         happened via the return code.
1036         ===========================================================*/
1037
1038       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_PSWD_EXPIRE);
1039    }
1040
1041    /*=== Save bsaObjectOwner (node name) value passed on Init ===*/
1042
1043    if (dsmNodeP)
1044       strcpy(xopenGbl.bsaObjectOwner, dsmNodeP);
1045
1046      /*================================================================
1047       Check to see if we saved away the 'expired password' return code.
1048       if so, return it to the caller.
1049       ================================================================*/
1050
1051    if (saverc)
1052       rc = saverc;
1053
1054    xlateRC(*BSAHandleP, rc, &bsaRC);
1055 #ifdef DEBUG_BUTC
1056         printf("BSAInit : Leaving Function. \n");
1057 #endif
1058    return (bsaRC);
1059 }
1060
1061 BSA_Int16 BSATerminate(
1062     long              BSAHandle
1063 )
1064 {
1065    dsInt16_t      rc = 0;
1066    BSA_Int16      bsaRC = 0;
1067    dsUint32_t     dsmHandle;
1068
1069    if(!dsm_init)
1070    {
1071 #ifdef DEBUG_BUTC
1072         printf("TSM library not mounted. \n");
1073 #endif
1074         if (dsm_MountLibrary())
1075         {
1076                 printf("TSM Library initialisation failed. \n");
1077                 return 1 ;
1078         }
1079 #ifdef DEBUG_BUTC
1080         printf("TSM Library initialisation SUCCESS. \n");
1081 #endif
1082    }
1083
1084    dsmHandle = BSAHandle;
1085    sprintf(traceStr2, "BSATerminate ENTRY: BSAHandle is %d.",
1086                       BSAHandle);
1087    ourTrace(dsmHandle, TrFL, traceStr2);
1088
1089    rc = AFSdsmTerminate(dsmHandle);
1090    dsmHandle = 0;
1091    xlateRC(dsmHandle, rc, &bsaRC);
1092
1093    return (bsaRC);
1094
1095 }
1096
1097 BSA_Int16 BSAChangeToken(
1098    long           BSAHandle,
1099    SecurityToken *oldTokenP,
1100    SecurityToken *newTokenP
1101 )
1102 {
1103    dsInt16_t      rc = 0;
1104    BSA_Int16      bsaRC = 0;
1105    dsUint32_t     dsmHandle;
1106
1107    if(!dsm_init)
1108    {
1109 #ifdef DEBUG_BUTC
1110         printf("TSM library not mounted. \n");
1111 #endif
1112         if (dsm_MountLibrary())
1113         {
1114                 printf("TSM Library initialisation failed. \n");
1115                 return 1 ;
1116         }
1117 #ifdef DEBUG_BUTC
1118         printf("TSM Library initialisation SUCCESS. \n");
1119 #endif
1120    }
1121
1122    dsmHandle = BSAHandle;
1123
1124    sprintf(traceStr2, "BSAChangeToken ENTRY: BSAHandle:%d old:>%s< new:>%s<",
1125            BSAHandle,oldTokenP,newTokenP);
1126    ourTrace(dsmHandle, TrFL, traceStr2);
1127
1128    rc = AFSdsmChangePW(dsmHandle, (char *)oldTokenP, (char *)newTokenP);
1129
1130    if (rc)
1131    {
1132       xlateRC(BSAHandle, rc, &bsaRC);
1133       XOPENRETURN(BSAHandle,"BSAChangeToken(AFSdsmChangePW)",
1134                   bsaRC,__FILE__,__LINE__);
1135    }
1136
1137    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_PSWD_EXPIRE); /* set off */
1138
1139     /*=== now query session info to populate the global structure ===*/
1140
1141    xopenGbl.dsmSessInfo.stVersion = ApiSessInfoVersion;
1142    rc = AFSdsmQuerySessInfo(dsmHandle,                /* Our session handle  */
1143                          &xopenGbl.dsmSessInfo);   /* Output structure.   */
1144    if (rc)
1145    {
1146       /*=== appl should call Terminate ===*/
1147       sprintf(traceStr2, "BSAChangeToken(AFSdsmQuerySessInfo): error rc = %d", rc);
1148       ourTrace(BSAHandle, TrFL, traceStr2);
1149    }
1150    xlateRC(BSAHandle, rc, &bsaRC);
1151    XOPENRETURN(BSAHandle,"BSAChangeToken",
1152                bsaRC,__FILE__,__LINE__);
1153 }
1154
1155 BSA_Int16 BSASetEnvironment(
1156     long     BSAHandle,
1157     char           **envP
1158 )
1159 {
1160    if(!dsm_init)
1161    {
1162 #ifdef DEBUG_BUTC
1163         printf("TSM library not mounted. \n");
1164 #endif
1165         if (dsm_MountLibrary())
1166         {
1167                 printf("TSM Library initialisation failed. \n");
1168                 return 1 ;
1169         }
1170 #ifdef DEBUG_BUTC
1171         printf("TSM Library initialisation SUCCESS. \n");
1172 #endif
1173    }
1174
1175    sprintf(traceStr2, "BSASetEnvironment ENTRY: BSAHandle:%d envP:>%p< ",
1176            BSAHandle,envP);
1177    ourTrace(BSAHandle, TrFL, traceStr2);
1178    XOPENRETURN(BSAHandle,"BSASetEnvironment",
1179                BSA_RC_BAD_CALL_SEQUENCE,__FILE__,__LINE__);
1180 }
1181
1182 BSA_Int16 BSAGetEnvironment(
1183    long           BSAHandle,
1184    ObjectOwner   *objOwnerP,
1185    char         **envP
1186 )
1187 {
1188    dsInt16_t   rc = 0;
1189    BSA_Int16   bsaRC = 0;
1190    dsUint32_t  dsmHandle;
1191    char        envString[ADSM_ENV_STRS][BSA_MAX_DESC];
1192    char        maxObjStr[6];  /* conversion field. value range is 16-256 */
1193    dsUint32_t  maxObjNum;
1194    dsInt16_t   i, j;
1195
1196    if(!dsm_init)
1197    {
1198 #ifdef DEBUG_BUTC
1199         printf("TSM library not mounted. \n");
1200 #endif
1201         if (dsm_MountLibrary())
1202         {
1203                 printf("TSM Library initialisation failed. \n");
1204                 return 1 ;
1205         }
1206 #ifdef DEBUG_BUTC
1207         printf("TSM Library initialisation SUCCESS. \n");
1208 #endif
1209    }
1210
1211    for (i=0; i<ADSM_ENV_STRS; i++)
1212    {
1213       memset(envString[i], 0x00, BSA_MAX_DESC);
1214    }
1215    sprintf(traceStr2, "BSAGetEnvironment ENTRY: BSAHandle:%d ObjOwner:'%s' appOwner:'%s' envP:>%p<.",
1216            BSAHandle,
1217            objOwnerP->bsaObjectOwner,
1218            objOwnerP->appObjectOwner,
1219            envP);
1220    ourTrace(BSAHandle, TrFL, traceStr2);
1221
1222    dsmHandle = BSAHandle;
1223
1224    /*===============================================================
1225     check if BSAInit has been done for now we have only one possible
1226     handle value - change in future
1227     ==============================================================*/
1228    if ((dsmHandle != FIRST_HANDLE) ||
1229       (xopenGbl.dsmSessInfo.stVersion != ApiSessInfoVersion))
1230        XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1231                    BSA_RC_BAD_CALL_SEQUENCE, __FILE__,__LINE__);
1232
1233    if (objOwnerP)
1234    {
1235       strcpy(objOwnerP->bsaObjectOwner, xopenGbl.dsmSessInfo.id);
1236       strcpy(objOwnerP->appObjectOwner, xopenGbl.dsmSessInfo.owner);
1237    }
1238    else
1239       XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1240                   BSA_RC_NULL_POINTER, __FILE__,__LINE__);
1241
1242    rc = AFSdsmQuerySessInfo(dsmHandle,                   /* Session Handle */
1243                          &xopenGbl.dsmSessInfo);       /* Output struct  */
1244
1245    if (rc)
1246       {
1247          sprintf(traceStr2, "BSAGetEnvironment(AFSdsmQuerySessInfo): error rc = %d", rc);
1248          ourTrace(dsmHandle, TrFL, traceStr2);
1249          AFSdsmTerminate(dsmHandle);
1250         /* *BSAHandleP = 0; */
1251       }
1252       else
1253       {
1254          sprintf(traceStr2, "BSAGetEnvironment: Actual node=%s, actual DSM owner=%s, ServerName=%s.",
1255                  xopenGbl.dsmSessInfo.id, xopenGbl.dsmSessInfo.owner, xopenGbl.dsmSessInfo.adsmServerName);
1256          ourTrace(dsmHandle, TrFL, traceStr2);
1257       }
1258
1259    strcpy(envString[0],"TSMSRVR=");
1260    strcat(envString[0],xopenGbl.dsmSessInfo.serverHost);
1261
1262    strcpy(envString[1],"TSMMAXOBJ=");
1263    maxObjNum = xopenGbl.dsmSessInfo.maxObjPerTxn;  /* convert to 32 bit */
1264    sprintf(maxObjStr,"%lu", maxObjNum );
1265    strcat(envString[1], maxObjStr);
1266
1267    strcpy(envString[2], "TSMSRVRSTANZA=");
1268    strcat(envString[2], xopenGbl.dsmSessInfo.adsmServerName);
1269
1270    sprintf(traceStr2, "BSAGetEnvironment Value : TSM Server '%s', TSM Max Object '%s',TSM Server STANZA '%s'",
1271          envString[0], envString[1], envString[2]);
1272    ourTrace(BSAHandle, TrFL, traceStr2);
1273
1274    for (i=0; i< ADSM_ENV_STRS; i++) {
1275      if ( *envP == NULL ) {  /* watch for NULL pointers */
1276        /* Allocating memory for *envP.*/
1277        *envP = (char *) malloc(sizeof(char) * BSA_MAX_DESC +1);
1278
1279        /* copy the content of envString[i] to *envP. */
1280         strcpy(*envP,envString[i]);
1281         envP++;
1282      }
1283    }
1284
1285    xlateRC(BSAHandle, rc, &bsaRC);
1286    XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1287                bsaRC,__FILE__,__LINE__)
1288 }
1289
1290 BSA_Int16 BSABeginTxn(
1291     long             BSAHandle
1292 )
1293 {
1294    if(!dsm_init)
1295    {
1296 #ifdef DEBUG_BUTC
1297         printf("TSM library not mounted. \n");
1298 #endif
1299         if (dsm_MountLibrary())
1300         {
1301                 printf("TSM Library initialisation failed. \n");
1302                 return 1 ;
1303         }
1304 #ifdef DEBUG_BUTC
1305         printf("TSM Library initialisation SUCCESS. \n");
1306 #endif
1307    }
1308
1309    sprintf(traceStr2, "BSABeginTxn ENTRY: BSAHandle:%d", BSAHandle);
1310    ourTrace(BSAHandle, TrFL, traceStr2);
1311   /*========================================================
1312    don't actually issue BeginTxn yet, because we will do our
1313    own for Get and Query
1314    ========================================================*/
1315
1316    xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_BSA_TXN); /* set on */
1317    XOPENRETURN(BSAHandle, "BSABeginTxn",
1318                BSA_RC_SUCCESS,__FILE__,__LINE__);
1319 }
1320
1321 BSA_Int16 BSAEndTxn(
1322     long           BSAHandle,
1323     Vote           vote
1324 )
1325 {
1326    dsInt16_t      rc = 0;
1327    BSA_Int16      bsaRC = 0;
1328    dsUint32_t     dsmHandle;
1329    dsUint8_t      dsmVote;
1330    dsUint16_t     reason ;
1331    char           rsMsg[DSM_MAX_RC_MSG_LENGTH + 1];
1332    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1333    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1334
1335    if(!dsm_init)
1336    {
1337 #ifdef DEBUG_BUTC
1338         printf("TSM library not mounted. \n");
1339 #endif
1340         if (dsm_MountLibrary())
1341         {
1342                 printf("TSM Library initialisation failed. \n");
1343                 return 1 ;
1344         }
1345 #ifdef DEBUG_BUTC
1346         printf("TSM Library initialisation SUCCESS. \n");
1347 #endif
1348    }
1349
1350    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1351    memset(rsMsg,        '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1352    memset(ourMessage,    '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1353
1354    sprintf(traceStr2, "BSAEndTxn ENTRY: BSAHandle:%d Vote:>%d<", BSAHandle, vote);
1355    ourTrace(BSAHandle, TrFL, traceStr2);
1356
1357    dsmHandle = BSAHandle;
1358
1359    if (xopenGbl.sessFlags & FL_IN_DSM_TXN)
1360    {
1361       if (vote == BSAVote_COMMIT)
1362          dsmVote = DSM_VOTE_COMMIT;
1363       else
1364          if (vote == BSAVote_ABORT)
1365             dsmVote = DSM_VOTE_ABORT;
1366          else
1367          {
1368             sprintf(traceStr2, "BSAEndTxn: invalid vote (%d)", vote);
1369             ourTrace(BSAHandle,TrFL, traceStr2);
1370             bsaRC = BSA_RC_INVALID_VOTE;
1371             XOPENRETURN(BSAHandle, "BSAEndTxn",bsaRC,__FILE__,__LINE__);
1372          }
1373
1374
1375       sprintf(traceStr2, "BSAEndTxn: issue AFSdsmEndTxn, vote=%s",
1376                   dsmVote == DSM_VOTE_COMMIT ? "COMMIT" : "ABORT");
1377       ourTrace(BSAHandle,TrFL, traceStr2);
1378       /*===========================================================
1379         check if this EndTxn call was proceeded by a Send call which
1380         returned WILL_ABORT. If so, make sure the vote is COMMIT
1381         so we will get the server's reason code.
1382         ===========================================================*/
1383       if (xopenGbl.sessFlags & FL_RC_WILL_ABORT)
1384       {
1385          dsmVote = DSM_VOTE_COMMIT;
1386
1387          sprintf(traceStr2, "BSAEndTxn: sproceeded by RC_WILL_ABORT, so use vote=COMMIT");
1388          ourTrace(BSAHandle,TrFL, traceStr2);
1389          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_RC_WILL_ABORT); /* set off*/
1390       }
1391
1392       rc = AFSdsmEndTxn(dsmHandle, dsmVote, &reason);
1393       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
1394
1395       /*====================================================
1396        if the caller wanted to Abort, then return rc=OK, not
1397        our usual 2302 and reason 3
1398        =====================================================*/
1399       if ((dsmVote ==  DSM_VOTE_ABORT)     &&
1400           (rc == DSM_RC_CHECK_REASON_CODE) &&
1401           (reason == DSM_RC_ABORT_BY_CLIENT))
1402
1403          rc = DSM_RC_OK;
1404
1405       if (rc)
1406       {
1407          sprintf(traceStr2, "BSAEndTxn(AFSdsmEndTxn) error rc = %d", rc);
1408          ourTrace(BSAHandle,TrFL, traceStr2);
1409
1410          AFSdsmRCMsg(BSAHandle, reason, rsMsg);
1411          sprintf(traceStr2, "BSAEndTxn: reason code = %d, Message='%s'", reason, rsMsg);
1412          ourTrace(BSAHandle,TrFL, traceStr2);
1413
1414          strcpy(ourMessage, ourRCMsg(reason, errPrefix));
1415          ourLogEvent_Ex(BSAHandle,logBoth, ourMessage, errPrefix, logSevError);
1416       }
1417       xlateRC(BSAHandle, rc, &bsaRC);
1418
1419       if (rc == DSM_RC_CHECK_REASON_CODE) /* return reason code instead */
1420       {
1421          xlateRC(BSAHandle, reason, &bsaRC);
1422       }
1423    }
1424
1425    /*=== check if Query was terminated ===*/
1426    if (xopenGbl.sessFlags & FL_IN_BSA_QRY)
1427    {
1428       AFSdsmEndQuery(dsmHandle);
1429       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1430    }
1431
1432    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_TXN); /* set off */
1433    XOPENRETURN(BSAHandle, "BSAEndTxn",
1434                bsaRC,__FILE__,__LINE__);
1435 }
1436
1437 void  BSAQueryApiVersion(
1438 ApiVersion       *BSAapiVerP
1439 )
1440
1441 {
1442    /*===============================================================
1443     Don't actually call the base QueryApiVersion call.
1444     Use the defines from custom.h since this is what the application
1445     sees in the header file. The constants should be the same,
1446     but may get out of sync occasionally.
1447     ===============================================================*/
1448    BSAapiVerP->version = BSA_API_VERSION;
1449    BSAapiVerP->release = BSA_API_RELEASE;
1450    BSAapiVerP->level   = BSA_API_LEVEL;
1451    return;
1452 }
1453
1454 BSA_Int16 BSAQueryObject(
1455 long              BSAHandle,
1456 QueryDescriptor  *BSAqryDescP,
1457 ObjectDescriptor *BSAobjDescP
1458 )
1459 {
1460    dsInt16_t      rc = 0;
1461    BSA_Int16      bsaRC = 0;
1462    dsUint32_t     dsmHandle;
1463    dsmObjName     objName;
1464    dsUint8_t      dsmObjType;
1465    dsmQueryType   query_type;
1466    dsmQueryBuff   *query_buff;
1467    DataBlk        qData;
1468    qryArchiveData archiveData;
1469    qryRespArchiveData respArchive;
1470    qryBackupData  backupData;
1471    qryRespBackupData  respBackup;
1472    BSAObjectOwner upperNode;  /* upper cased node name */
1473
1474    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1475    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1476
1477    if(!dsm_init)
1478    {
1479 #ifdef DEBUG_BUTC
1480         printf("TSM library not mounted. \n");
1481 #endif
1482         if (dsm_MountLibrary())
1483         {
1484                 printf("TSM Library initialisation failed. \n");
1485                 return 1 ;
1486         }
1487 #ifdef DEBUG_BUTC
1488         printf("TSM Library initialisation SUCCESS. \n");
1489 #endif
1490    }
1491
1492    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1493    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1494
1495    dsmHandle = BSAHandle;
1496
1497    memset(&backupData, 0x00, sizeof(qryBackupData));
1498
1499    sprintf(traceStr2, "BSAQueryObject ENTRY: BSAHandle:%d ObjOwner(qryDesc):'%s' appOwner(qryDesc):'%s' \n ObjName(qryDesc):'%.*s%.*s' \n copyType:%d ObjectType:%d status:%d ",
1500           BSAHandle,
1501           BSAqryDescP->owner.bsaObjectOwner,
1502           BSAqryDescP->owner.appObjectOwner,
1503           100,BSAqryDescP->objName.objectSpaceName,
1504           100,BSAqryDescP->objName.pathName,
1505           BSAqryDescP->copyType,
1506           BSAqryDescP->objectType,
1507           BSAqryDescP->status);
1508    ourTrace(BSAHandle, TrFL, traceStr2);
1509
1510    /*=====================================================
1511     init objDesc area to 0's before we start to erase any
1512     garbage that might be there.
1513     =====================================================*/
1514    memset(BSAobjDescP, 0x00, sizeof(ObjectDescriptor));
1515
1516    /*=== init global look ahead pointer to NULL ===*/
1517    if (xopenGbl.nextQryP != NULL)
1518    {
1519       dsFree(xopenGbl.nextQryP);
1520       xopenGbl.nextQryP = NULL;
1521    }
1522
1523    /*=========================================================
1524     if the node name is different - we won't query it compare
1525     both the value passed on the BSAInit and the final value
1526     used for the session (which may be different for Generate).
1527     =========================================================*/
1528    strcpy(upperNode, BSAqryDescP->owner.bsaObjectOwner);
1529    StrUpper(upperNode);
1530    if ((strcmp(upperNode, xopenGbl.dsmSessInfo.id)) &&
1531       (strcmp(BSAqryDescP->owner.bsaObjectOwner, xopenGbl.bsaObjectOwner)))
1532    {
1533       sprintf(traceStr2,
1534       "BSAQueryObject: BSAObjectOwner(%s) doesn't match value for session(%s).", upperNode, xopenGbl.dsmSessInfo.id);
1535       ourTrace(BSAHandle,TrFL, traceStr2);
1536       bsaRC = ADSM_RC_INVALID_NODE;
1537       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1538       ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1539       XOPENRETURN(BSAHandle, "BSAQueryObject",
1540                   bsaRC,__FILE__,__LINE__);
1541    }
1542
1543    /*=====================================================
1544      currently BSA_MAX_OSNAME = DSM_MAX_FSNAME_LENGTH
1545      if this changes, use strncpy
1546      ====================================================*/
1547    if (strlen(BSAqryDescP->objName.objectSpaceName) > BSA_MAX_OSNAME)
1548    {
1549       sprintf(traceStr2, "BSAQueryObject: objectSpaceName too long (%d).",
1550               strlen(BSAqryDescP->objName.objectSpaceName));
1551       ourTrace(BSAHandle,TrFL, traceStr2);
1552       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
1553       XOPENRETURN(BSAHandle, "BSAQueryObject",
1554                   bsaRC,__FILE__,__LINE__);
1555    }
1556    /*=================================================================
1557      the entire pathname gets copied into hl during parsing, so check
1558      for that max len as well. For now these are the same value.
1559      ================================================================*/
1560    if (strlen(BSAqryDescP->objName.pathName) >
1561        min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
1562    {
1563       sprintf(traceStr2, "BSAQueryObject: pathName too long (%d)",
1564               strlen(BSAqryDescP->objName.pathName));
1565       ourTrace(BSAHandle, TrFL, traceStr2);
1566       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
1567       XOPENRETURN(BSAHandle, "BSAQueryObject",
1568                   bsaRC,__FILE__,__LINE__);
1569    }
1570    if ((BSAqryDescP->objectType == BSAObjectType_FILE) ||
1571        (BSAqryDescP->objectType == BSAObjectType_DATABASE))
1572       dsmObjType = DSM_OBJ_FILE;
1573    else
1574       if (BSAqryDescP->objectType == BSAObjectType_DIRECTORY)
1575          dsmObjType = DSM_OBJ_DIRECTORY;
1576       else
1577          if (BSAqryDescP->objectType == BSAObjectType_ANY)
1578             dsmObjType = DSM_OBJ_ANY_TYPE;
1579          else
1580          {
1581              sprintf(traceStr2,
1582                      "BSAQueryObject: invalid objectType (%d)", BSAqryDescP->objectType);
1583              ourTrace(BSAHandle,TrFL, traceStr2);
1584              bsaRC = ADSM_RC_INVALID_OBJTYPE;
1585              strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1586              ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1587              XOPENRETURN(BSAHandle, "BSAQueryObject",
1588                          bsaRC,__FILE__,__LINE__);
1589          }
1590
1591    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
1592    {
1593       sprintf(traceStr2, "BSAQueryObject: issued without BSABeginTxn");
1594       ourTrace(BSAHandle,TrFL, traceStr2);
1595       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
1596       XOPENRETURN(BSAHandle, "BSAQueryObject",
1597                   bsaRC,__FILE__,__LINE__);
1598    }
1599
1600    /* store object name in ADSM structure */
1601    strcpy(objName.fs,BSAqryDescP->objName.objectSpaceName) ;
1602
1603    if (!strcmp(BSAqryDescP->objName.pathName, "/*")) /* if they use a wildcard */
1604    {  /* we need to use a wild card on both hl and ll since the path gets split */
1605       strcpy(objName.hl, "*");  /* don't include delimiter in case there is
1606                              no hl */
1607       strcpy(objName.ll, "/*");
1608    }
1609    else
1610       xparsePath(BSAHandle, BSAqryDescP->objName.pathName, objName.hl, objName.ll);
1611
1612       objName.objType = dsmObjType ;
1613
1614       /*=== save copy type for GetNextQuery call later ===*/
1615       xopenGbl.copyType = BSAqryDescP->copyType;
1616
1617       if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1618       {
1619          if (strlen(BSAqryDescP->desc) > ADSM_MAX_DESC)
1620          {
1621
1622             sprintf(traceStr2, "BSAQueryObject: description longer than ADSM max (%d). ", strlen(BSAqryDescP->desc));
1623             ourTrace(BSAHandle,TrFL, traceStr2);
1624             bsaRC = BSA_RC_DESC_TOO_LONG;
1625             XOPENRETURN(BSAHandle, "BSAQueryObject",
1626                         bsaRC,__FILE__,__LINE__);
1627          }
1628
1629          archiveData.stVersion = qryArchiveDataVersion;
1630          archiveData.objName   = &objName;
1631          archiveData.owner     = (char *)&BSAqryDescP->owner.appObjectOwner;
1632
1633          /*=================================================================
1634            in the tm structure the month count starts with 0 and year is
1635            the value since 1900.
1636            Adjust the year value only if it isn't one of the boundary values
1637            =================================================================*/
1638
1639          archiveData.insDateLowerBound.year   = BSAqryDescP->createTimeLB.tm_year;
1640          if (archiveData.insDateLowerBound.year != ADSM_LOWEST_BOUND)
1641             archiveData.insDateLowerBound.year  += 1900;
1642          archiveData.insDateLowerBound.month  = BSAqryDescP->createTimeLB.tm_mon+1;
1643          archiveData.insDateLowerBound.day    = BSAqryDescP->createTimeLB.tm_mday;
1644          archiveData.insDateLowerBound.hour   = BSAqryDescP->createTimeLB.tm_hour;
1645          archiveData.insDateLowerBound.minute = BSAqryDescP->createTimeLB.tm_min;
1646          archiveData.insDateLowerBound.second = BSAqryDescP->createTimeLB.tm_sec;
1647
1648          archiveData.insDateUpperBound.year   = BSAqryDescP->createTimeUB.tm_year;
1649          if (archiveData.insDateUpperBound.year != ADSM_HIGHEST_BOUND)
1650              archiveData.insDateUpperBound.year  += 1900;
1651          archiveData.insDateUpperBound.month  = BSAqryDescP->createTimeUB.tm_mon+1;
1652          archiveData.insDateUpperBound.day    = BSAqryDescP->createTimeUB.tm_mday;
1653          archiveData.insDateUpperBound.hour   = BSAqryDescP->createTimeUB.tm_hour;
1654          archiveData.insDateUpperBound.minute = BSAqryDescP->createTimeUB.tm_min;
1655          archiveData.insDateUpperBound.second = BSAqryDescP->createTimeUB.tm_sec;
1656
1657          archiveData.expDateLowerBound.year   = BSAqryDescP->expireTimeLB.tm_year;
1658          if (archiveData.expDateLowerBound.year != ADSM_LOWEST_BOUND)
1659              archiveData.expDateLowerBound.year  += 1900;
1660          archiveData.expDateLowerBound.month  = BSAqryDescP->expireTimeLB.tm_mon+1;
1661          archiveData.expDateLowerBound.day    = BSAqryDescP->expireTimeLB.tm_mday;
1662          archiveData.expDateLowerBound.hour   = BSAqryDescP->expireTimeLB.tm_hour;
1663          archiveData.expDateLowerBound.minute = BSAqryDescP->expireTimeLB.tm_min;
1664          archiveData.expDateLowerBound.second = BSAqryDescP->expireTimeLB.tm_sec;
1665
1666          archiveData.expDateUpperBound.year   = BSAqryDescP->expireTimeUB.tm_year;
1667          if (archiveData.expDateUpperBound.year != ADSM_HIGHEST_BOUND)
1668             archiveData.expDateUpperBound.year  += 1900;
1669          archiveData.expDateUpperBound.month  = BSAqryDescP->expireTimeUB.tm_mon+1;
1670          archiveData.expDateUpperBound.day    = BSAqryDescP->expireTimeUB.tm_mday;
1671          archiveData.expDateUpperBound.hour   = BSAqryDescP->expireTimeUB.tm_hour;
1672          archiveData.expDateUpperBound.minute = BSAqryDescP->expireTimeUB.tm_min;
1673          archiveData.expDateUpperBound.second = BSAqryDescP->expireTimeUB.tm_sec;
1674
1675          archiveData.descr = (char *)&BSAqryDescP->desc;
1676          query_type = qtArchive;
1677          query_buff = (dsmQueryBuff *)&archiveData;
1678
1679          qData.stVersion = DataBlkVersion;
1680          qData.bufferLen = sizeof(qryRespArchiveData);
1681          qData.bufferPtr = (char *)&respArchive;
1682          respArchive.stVersion = qryRespArchiveDataVersion;
1683    }
1684    else
1685       if (BSAqryDescP->copyType == BSACopyType_BACKUP)
1686       {
1687          if (BSAqryDescP->status == BSAObjectStatus_ACTIVE)
1688             backupData.objState  = DSM_ACTIVE;
1689          else
1690             if (BSAqryDescP->status == BSAObjectStatus_INACTIVE)
1691                backupData.objState  = DSM_INACTIVE;
1692             else
1693                if (BSAqryDescP->status == BSAObjectStatus_ANY)
1694                   backupData.objState  = DSM_ANY_MATCH;
1695                else
1696                {
1697                    sprintf(traceStr2,
1698                            "BSAQueryObject: invalid status (%d)",
1699                             BSAqryDescP->status);
1700                    ourTrace(BSAHandle,TrFL, traceStr2);
1701                    bsaRC = ADSM_RC_INVALID_STATUS;
1702                    strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1703                    ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1704                    XOPENRETURN(BSAHandle, "BSAQueryObject",
1705                                bsaRC,__FILE__,__LINE__);
1706                }
1707
1708             backupData.stVersion = qryBackupDataVersion;
1709             backupData.objName   = &objName;
1710             backupData.owner     = (char *)&BSAqryDescP->owner.appObjectOwner;
1711
1712             query_type = qtBackup;
1713             query_buff = (dsmQueryBuff *)&backupData;
1714
1715             qData.stVersion = DataBlkVersion;
1716             qData.bufferLen = sizeof(qryRespBackupData);
1717             qData.bufferPtr = (char *)&respBackup;
1718             respBackup.stVersion = qryRespBackupDataVersion;;
1719       }
1720       else
1721       {
1722          sprintf(traceStr2,
1723                            "BSAQueryObject: invalid copyType (%d)",
1724                             BSAqryDescP->copyType);
1725          ourTrace(BSAHandle,TrFL, traceStr2);
1726          bsaRC = ADSM_RC_INVALID_COPYTYPE;
1727          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1728          ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1729          XOPENRETURN(BSAHandle, "BSAQueryObject",
1730                      bsaRC,__FILE__,__LINE__);
1731       }
1732
1733       /*=== now set flag for query ===*/
1734       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_BSA_QRY); /* set on */
1735
1736       if ((rc = AFSdsmBeginQuery(dsmHandle,query_type,query_buff)))
1737       {
1738
1739          sprintf(traceStr2, "BSAQueryObject(AFSdsmBeginQuery) error rc = %d", rc);
1740          ourTrace(BSAHandle,TrFL, traceStr2);
1741          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1742          xlateRC(BSAHandle, rc, &bsaRC);
1743          XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmBeginQuery)",
1744                                  bsaRC,__FILE__,__LINE__);
1745       }
1746
1747       rc = AFSdsmGetNextQObj(dsmHandle,&qData);
1748       if (((rc == DSM_RC_OK) || (rc == DSM_RC_MORE_DATA)) && qData.numBytes)
1749       {
1750          BSAobjDescP->version = ObjectDescriptorVersion;
1751          strcpy(BSAobjDescP->Owner.bsaObjectOwner, xopenGbl.dsmSessInfo.id);
1752          BSAobjDescP->copyType = BSAqryDescP->copyType;
1753          strcpy(BSAobjDescP->cGName, "\0");   /* no copy group name returned */
1754
1755          if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1756          {
1757             fillArchiveResp(dsmHandle, BSAobjDescP, &respArchive);
1758          }
1759          else /* backup */
1760          {
1761             fillBackupResp(dsmHandle, BSAobjDescP, &respBackup);
1762          }
1763          /*=== look ahead and see if there is more or if this is really done ===*/
1764          rc = AFSdsmGetNextQObj(dsmHandle,&qData);
1765          if (( (rc == DSM_RC_OK) || (rc == DSM_RC_MORE_DATA)) && qData.numBytes)
1766          { /*=== save the response we just got for later call ===*/
1767             if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1768             {
1769                if (!(xopenGbl.nextQryP = (char *)dsMalloc(sizeof(qryRespArchiveData))))
1770                {
1771
1772                   sprintf(traceStr2, "BSAQueryObject: no memory for look ahead buffer");
1773                   ourTrace(BSAHandle,TrFL, traceStr2);
1774                   xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1775                   bsaRC = BSA_RC_NO_RESOURCES;
1776                   XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmGetNextQObj)",
1777                               bsaRC,__FILE__,__LINE__);
1778                }
1779                memcpy(xopenGbl.nextQryP, &respArchive, sizeof(qryRespArchiveData));
1780             }
1781             else
1782             {
1783                if (!(xopenGbl.nextQryP = (char *)dsMalloc(sizeof(qryRespBackupData))))
1784                {
1785
1786                   sprintf(traceStr2, "BSAQueryObject: no memory for look ahead buffer");
1787                   ourTrace(BSAHandle,TrFL, traceStr2);
1788                   xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1789                   bsaRC = BSA_RC_NO_RESOURCES;
1790                   XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmGetNextQObj)",
1791                               bsaRC,__FILE__,__LINE__);
1792
1793                }
1794                memcpy(xopenGbl.nextQryP, &respBackup, sizeof(qryRespBackupData));
1795             }
1796          }
1797       else
1798       {
1799
1800          sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d", rc);
1801          ourTrace(BSAHandle,TrFL, traceStr2);
1802          AFSdsmEndQuery(dsmHandle);
1803          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1804       }
1805
1806    }
1807    else /* could be FINISHED or an error */
1808    {
1809
1810       sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d", rc);
1811       ourTrace(BSAHandle,TrFL, traceStr2);
1812       AFSdsmEndQuery(dsmHandle);
1813       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1814    }
1815
1816    if (rc == DSM_RC_OK)
1817    {
1818       sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d, ObjOwner(objDesc):'%s' appOwner(objDesc):'%s' \n ObjName(objDesc):'%.*s%.*s' \n copyType:%d copyId:'%d %d' cGName:'%s'",
1819        rc,
1820        BSAobjDescP->Owner.bsaObjectOwner,
1821        BSAobjDescP->Owner.appObjectOwner,
1822        100,BSAobjDescP->objName.objectSpaceName,
1823        100,BSAobjDescP->objName.pathName,
1824        BSAobjDescP->copyType,
1825        BSAobjDescP->copyId.left,
1826        BSAobjDescP->copyId.right,
1827        BSAobjDescP->cGName == NULL ? "" : BSAobjDescP->cGName);
1828        ourTrace(BSAHandle,TrFL, traceStr2);
1829    }
1830
1831    xlateRC(BSAHandle, rc, &bsaRC);
1832    XOPENRETURN(BSAHandle, "BSAQueryObject",
1833                bsaRC, __FILE__,__LINE__);
1834 }
1835
1836 BSA_Int16 BSAGetObject(
1837     long              BSAHandle,
1838     ObjectDescriptor *BSAobjDescP,
1839     DataBlock        *BSAdataBlockP
1840 )
1841 {
1842    dsInt16_t      rc = 0;
1843    dsInt16_t      rc1 = 0;
1844    BSA_Int16      bsaRC = 0;
1845    dsUint32_t     dsmHandle;
1846    DataBlk        getBlk;
1847    dsmGetType     getType;
1848    dsmGetList     dsmObjList ;
1849    char           rcMsg[DSM_MAX_RC_MSG_LENGTH + 1];
1850    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1851    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1852
1853    if(!dsm_init)
1854    {
1855 #ifdef DEBUG_BUTC
1856         printf("TSM library not mounted. \n");
1857 #endif
1858         if (dsm_MountLibrary())
1859         {
1860                 printf("TSM Library initialisation failed. \n");
1861                 return 1 ;
1862         }
1863 #ifdef DEBUG_BUTC
1864         printf("TSM Library initialisation SUCCESS. \n");
1865 #endif
1866    }
1867
1868    dsmHandle = BSAHandle;
1869
1870    memset(rcMsg,         '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1871    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1872    memset(ourMessage,    '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1873
1874    sprintf(traceStr2, "BSAGetObject ENTRY: BSAHandle:%d version:%d copyType:%d copyId:'%d %d' \n bufferLen:%d numBytes:%d ",
1875            BSAHandle,
1876            BSAobjDescP->version,
1877            BSAobjDescP->copyType,
1878            BSAobjDescP->copyId.left,
1879            BSAobjDescP->copyId.right,
1880            BSAdataBlockP->bufferLen,
1881            BSAdataBlockP->numBytes);
1882    ourTrace(BSAHandle, TrFL, traceStr2);
1883
1884    xopenGbl.oper = OPER_RECV_START;    /* save state for EndData later */
1885
1886    if (BSAobjDescP->version != ObjectDescriptorVersion)
1887    {
1888       sprintf(traceStr2,"Warning: BSAGetObject: objectDesc.version unexpected %d.", BSAobjDescP->version);
1889       ourTrace(BSAHandle,TrFL, traceStr2);
1890       /*==================================================================
1891        don't treat this as an error now since it isn't defined in the spec
1892        bsaRC = ADSM_RC_INVALID_ST_VER;
1893        return(bsaRC);
1894        =================================================================*/
1895    }
1896
1897    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
1898    {
1899       sprintf(traceStr2, "BSAGetObject: issued without BSABeginTxn");
1900       ourTrace(BSAHandle,TrFL, traceStr2);
1901       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
1902       XOPENRETURN(BSAHandle, "BSAGetObject",
1903                   bsaRC,__FILE__,__LINE__);
1904    }
1905
1906    /*=== Get the data ===*/
1907    if (BSAobjDescP->copyType == BSACopyType_ARCHIVE)
1908       getType = gtArchive;
1909    else
1910       if (BSAobjDescP->copyType == BSACopyType_BACKUP)
1911          getType = gtBackup;
1912       else
1913       {
1914          sprintf(traceStr2,
1915                            "BSAGetObject: invalid copyType (%d)",
1916                             BSAobjDescP->copyType);
1917          ourTrace(BSAHandle,TrFL, traceStr2);
1918          bsaRC = ADSM_RC_INVALID_COPYTYPE;
1919          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1920          ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1921          XOPENRETURN(BSAHandle, "BSAGetObject",
1922                      bsaRC,__FILE__,__LINE__);
1923       }
1924
1925    /*=== now update state since we'll issue a base API call ===*/
1926    xopenGbl.oper = OPER_RECV_ISSUED;    /* save state for EndData later */
1927    /*=== setup for a single object get ===*/
1928
1929    dsmObjList.stVersion = dsmGetListVersion ;
1930    dsmObjList.numObjId = 1 ;
1931    dsmObjList.objId = (ObjID *)dsMalloc(sizeof(ObjID) * dsmObjList.numObjId) ;
1932
1933    dsmObjList.objId[0].hi = BSAobjDescP->copyId.left ;
1934    dsmObjList.objId[0].lo = BSAobjDescP->copyId.right ;
1935
1936    if ((rc = AFSdsmBeginGetData(dsmHandle,bTrue,   /* always say MountWait */
1937                              getType,
1938                              &dsmObjList)) != DSM_RC_OK)
1939    {
1940       sprintf(traceStr2, "BSAGetObject: Call to AFSdsmBeginGetData error rc = %d", rc);
1941       ourTrace(BSAHandle,TrFL, traceStr2);
1942       xlateRC(BSAHandle, rc, &bsaRC);
1943       XOPENRETURN(BSAHandle, "BSAGetObject(AFSdsmBeginGetData)",
1944                   bsaRC,__FILE__,__LINE__);
1945    }
1946
1947    /*********************************************************************/
1948    getBlk.stVersion = DataBlkVersion ;
1949    getBlk.bufferPtr = BSAdataBlockP->bufferPtr ;
1950    getBlk.bufferLen = BSAdataBlockP->bufferLen;
1951    getBlk.numBytes  = 0;
1952
1953    rc = AFSdsmGetObj(dsmHandle, &(dsmObjList.objId[0]), &getBlk) ;
1954
1955    if ((rc == DSM_RC_FINISHED) &&
1956        (getBlk.numBytes != 0))    /* actually is data received */
1957       rc = DSM_RC_MORE_DATA;      /* use different rc for consistency */
1958                                   /* with Query. No data returned */
1959                                   /* if rc = FINISHED.     */
1960    if ((rc == DSM_RC_FINISHED) ||
1961        (rc == DSM_RC_MORE_DATA))
1962    {
1963       /*=== data is already in the buffer ===*/
1964       BSAdataBlockP->numBytes = (BSA_UInt16)getBlk.numBytes;
1965    }
1966    else
1967    {
1968       /*=== appl may call BSAEndData to clean up trxn but don't count on it... ===*/
1969       rc1 = AFSdsmEndGetObj(dsmHandle);
1970       rc1 = AFSdsmEndGetData(dsmHandle);
1971       xopenGbl.sessFlags =
1972                (xopenGbl.sessFlags | FL_END_DATA_DONE);  /* turn flag on */
1973     }
1974
1975    xlateRC(BSAHandle, rc, &bsaRC);
1976    XOPENRETURN(BSAHandle, "BSAGetObject",
1977                bsaRC,__FILE__,__LINE__);
1978 }
1979
1980 BSA_Int16 BSAGetData(
1981     long              BSAHandle,
1982     DataBlock        *BSAdataBlockP
1983 )
1984 {
1985    dsInt16_t      rc = 0;
1986    dsInt16_t      rc1 = 0;
1987    BSA_Int16      bsaRC = 0;
1988    dsUint32_t     dsmHandle;
1989    DataBlk        getBlk;
1990
1991    if(!dsm_init)
1992    {
1993 #ifdef DEBUG_BUTC
1994         printf("TSM library not mounted. \n");
1995 #endif
1996         if (dsm_MountLibrary())
1997         {
1998                 printf("TSM Library initialisation failed. \n");
1999                 return 1 ;
2000         }
2001 #ifdef DEBUG_BUTC
2002         printf("TSM Library initialisation SUCCESS. \n");
2003 #endif
2004    }
2005
2006    dsmHandle = BSAHandle;
2007
2008
2009    sprintf(traceStr2, "BSAGetData ENTRY: BSAHandle:%d, bufferLen:%d, numBytes:%d",
2010            BSAHandle,
2011            BSAdataBlockP->bufferLen,
2012            BSAdataBlockP->numBytes);
2013    ourTrace(BSAHandle,TrFL, traceStr2);
2014
2015    getBlk.stVersion = DataBlkVersion ;
2016    getBlk.bufferPtr = BSAdataBlockP->bufferPtr ;
2017    getBlk.bufferLen = BSAdataBlockP->bufferLen;
2018    getBlk.numBytes  = 0;
2019
2020    rc = AFSdsmGetData(dsmHandle, &getBlk) ;
2021
2022    if ((rc == DSM_RC_FINISHED) &&
2023        (getBlk.numBytes != 0))      /* actually is data received */
2024       rc = DSM_RC_MORE_DATA;        /* use different rc for consistency */
2025                                     /* with Query. No data returned */
2026                                     /* if rc = FINISHED.     */
2027
2028    if ((rc == DSM_RC_FINISHED) ||
2029        (rc == DSM_RC_MORE_DATA))
2030    {
2031       /*=== data is already in the buffer ===*/
2032       BSAdataBlockP->numBytes = (BSA_UInt16)getBlk.numBytes;
2033    }
2034    else
2035    {
2036       sprintf(traceStr2, "BSAGetData: Call to AFSdsmGetData error rc = %d", rc);
2037       ourTrace(BSAHandle, TrFL,traceStr2);
2038
2039       /*=== appl may call BSAEndData to clean up trxn but don't count on it... ===*/
2040       rc1 = AFSdsmEndGetObj(dsmHandle);
2041       rc1 = AFSdsmEndGetData(dsmHandle);
2042       xopenGbl.sessFlags =
2043                (xopenGbl.sessFlags | FL_END_DATA_DONE);  /* turn flag on */
2044    }
2045    xlateRC(BSAHandle, rc, &bsaRC);
2046    XOPENRETURN(BSAHandle, "BSAGetData(AFSdsmGetData)",
2047                bsaRC,__FILE__,__LINE__);
2048 }
2049
2050 BSA_Int16 BSASendData(
2051     long           BSAHandle,
2052     DataBlock     *BSAdataBlockP
2053 )
2054 {
2055    dsInt16_t      rc = 0;
2056    BSA_Int16      bsaRC = 0;
2057    dsUint32_t     dsmHandle;
2058    DataBlk        dataBlkArea;
2059
2060    if(!dsm_init)
2061    {
2062 #ifdef DEBUG_BUTC
2063         printf("TSM library not mounted. \n");
2064 #endif
2065         if (dsm_MountLibrary())
2066         {
2067                 printf("TSM Library initialisation failed. \n");
2068                 return 1 ;
2069         }
2070 #ifdef DEBUG_BUTC
2071         printf("TSM Library initialisation SUCCESS. \n");
2072 #endif
2073    }
2074
2075    dsmHandle = BSAHandle;
2076
2077
2078    sprintf(traceStr2, "BSASendData ENTRY: BSAHandle:%d bufferLen: %d numBytes: %d ",
2079            BSAHandle,
2080            BSAdataBlockP->bufferLen,
2081            BSAdataBlockP->numBytes);
2082    ourTrace(BSAHandle, TrFL, traceStr2);
2083
2084    /*=== check for NULL dataBlock pointer ===*/
2085    if (BSAdataBlockP == NULL)
2086       XOPENRETURN(BSAHandle, "BSASendData",
2087                   BSA_RC_NULL_POINTER,__FILE__,__LINE__);
2088       dataBlkArea.stVersion = DataBlkVersion ;
2089       dataBlkArea.bufferPtr = BSAdataBlockP->bufferPtr ;
2090       dataBlkArea.bufferLen = BSAdataBlockP->bufferLen;
2091
2092       rc = AFSdsmSendData(dsmHandle, &dataBlkArea);
2093
2094       if (rc)
2095       {
2096
2097          sprintf(traceStr2, "BSASendData(AFSdsmSendData) error rc = %d", rc);
2098          ourTrace(BSAHandle,TrFL, traceStr2);
2099
2100          if (rc == DSM_RC_WILL_ABORT)  /* save flag */
2101             xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_RC_WILL_ABORT);
2102       }
2103       BSAdataBlockP->numBytes = (BSA_UInt16)dataBlkArea.numBytes;
2104       sprintf(traceStr2, "BSASendData(AFSdsmSendData): BSAHandle:%d bufferLen: %d numBytes sent: %d ",
2105            BSAHandle,
2106            BSAdataBlockP->bufferLen,
2107            BSAdataBlockP->numBytes);
2108       ourTrace(BSAHandle, TrFL, traceStr2);
2109
2110       xlateRC(BSAHandle, rc, &bsaRC);
2111       XOPENRETURN(BSAHandle, "BSASendData",
2112                   BSA_RC_SUCCESS,__FILE__,__LINE__);
2113 }
2114
2115 BSA_Int16 BSAEndData(
2116     long          BSAHandle
2117 )
2118 {
2119    dsInt16_t      rc = 0;
2120    dsInt16_t      rc1 = 0;
2121    BSA_Int16      bsaRC = 0;
2122    dsUint32_t     dsmHandle;
2123
2124    if(!dsm_init)
2125    {
2126 #ifdef DEBUG_BUTC
2127         printf("TSM library not mounted. \n");
2128 #endif
2129         if (dsm_MountLibrary())
2130         {
2131                 printf("TSM Library initialisation failed. \n");
2132                 return 1 ;
2133         }
2134 #ifdef DEBUG_BUTC
2135         printf("TSM Library initialisation SUCCESS. \n");
2136 #endif
2137    }
2138
2139    dsmHandle = BSAHandle;
2140
2141
2142    sprintf(traceStr2, "BSAEndData ENTRY: BSAHandle:%d", BSAHandle);
2143    ourTrace(BSAHandle,TrFL, traceStr2);
2144
2145    /*=======================================================
2146      check the state - don't issue base API call unless one
2147      was called previously, or else we get a sequence error.
2148      ======================================================*/
2149
2150    if (xopenGbl.oper == OPER_SEND_ISSUED)
2151    {
2152       rc = AFSdsmEndSendObj(dsmHandle);
2153       if (rc)
2154       {
2155
2156          sprintf(traceStr2, "BSAEndData(AFSdsmEndSendObj) error rc = %d", rc);
2157          ourTrace(BSAHandle,TrFL, traceStr2);
2158          xlateRC(BSAHandle, rc, &bsaRC);
2159       }
2160    }
2161    else
2162       if (xopenGbl.oper == OPER_RECV_ISSUED)
2163       {
2164           if (xopenGbl.sessFlags & FL_END_DATA_DONE)   /* EndData processing */
2165              xopenGbl.sessFlags =                     /*  already done */
2166                    (xopenGbl.sessFlags ^ FL_END_DATA_DONE);  /* turn flag off */
2167          else
2168          {
2169             rc = AFSdsmEndGetObj(dsmHandle);
2170             if (rc)
2171             {
2172                sprintf(traceStr2, "BSAEndData(AFSdsmEndGetObj) error rc = %d", rc);
2173                ourTrace(BSAHandle, TrFL, traceStr2);
2174
2175                /*==============================================================
2176                 this may get 'Out of sequence error' if previous GetObject
2177                 had rc=2 (no match). Don't return this to caller - too confusing
2178                 ===============================================================*/
2179                if (rc != DSM_RC_BAD_CALL_SEQUENCE)
2180                xlateRC(BSAHandle, rc, &bsaRC);
2181             }
2182
2183             rc = AFSdsmEndGetData(dsmHandle);
2184             if (rc)
2185             {
2186                sprintf(traceStr2, "BSAEndData(AFSdsmEndGetData) error rc = %d", rc);
2187                ourTrace(BSAHandle, TrFL, traceStr2);
2188                xlateRC(BSAHandle, rc, &bsaRC);
2189             }
2190          }
2191       }
2192    else  /* invalid state */
2193       if ((xopenGbl.oper != OPER_RECV_START) &&
2194           (xopenGbl.oper != OPER_SEND_START))
2195       {
2196          sprintf(traceStr2, "BSAEndData: BSAEndData but not Send or Recv");
2197          ourTrace(BSAHandle,TrFL, traceStr2);
2198          bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2199       }
2200
2201    xopenGbl.oper = OPER_NONE;
2202    XOPENRETURN(BSAHandle, "BSAEndData",bsaRC,__FILE__,__LINE__);
2203 }
2204
2205 BSA_Int16 BSACreateObject(
2206     long              BSAHandle,
2207     ObjectDescriptor *BSAobjDescP,
2208     DataBlock        *BSAdataBlockP
2209 )
2210 {
2211    dsInt16_t          rc = 0;
2212    BSA_Int16          bsaRC = 0;
2213    dsUint32_t         dsmHandle;
2214    regFSData          regFilespace ;
2215    dsmObjName         objName ;
2216    ObjAttr            objAttrArea;
2217    sndArchiveData     archData;
2218    DataBlk            dataBlkArea;
2219    dsmSendType        sendType;
2220    dsUint8_t          dsmObjType;
2221    XAPIObjInfo        xapiObjInfo;
2222    mcBindKey          mcBindKey;
2223    BSAObjectOwner     upperNode;  /* upper cased node name */
2224    char               errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
2225    char               ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
2226
2227    if(!dsm_init)
2228    {
2229 #ifdef DEBUG_BUTC
2230         printf("TSM library not mounted. \n");
2231 #endif
2232         if (dsm_MountLibrary())
2233         {
2234                 printf("TSM Library initialisation failed. \n");
2235                 return 1 ;
2236         }
2237 #ifdef DEBUG_BUTC
2238         printf("TSM Library initialisation SUCCESS. \n");
2239 #endif
2240    }
2241
2242    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2243    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2244
2245    dsmHandle = BSAHandle;
2246
2247    if (BSAobjDescP != NULL && BSAdataBlockP != NULL)
2248    {
2249    sprintf(traceStr2, "BSACreateObject ENTRY: BSAHandle:%d ObjOwner:'%s' appOwner:'%s' \n ObjName:'%.*s%.*s' \n objType:%d  size:'%d %d' resourceType:'%s'  \n bufferLen:%d numBytes:%d ",
2250
2251            BSAHandle,
2252            BSAobjDescP->Owner.bsaObjectOwner[0] != '\0' ? BSAobjDescP->Owner.bsaObjectOwner : "",
2253            BSAobjDescP->Owner.appObjectOwner[0] != '\0' ?  BSAobjDescP->Owner.appObjectOwner : "",
2254            100,BSAobjDescP->objName.objectSpaceName[0] != '\0' ? BSAobjDescP->objName.objectSpaceName
2255            : "",
2256            100,BSAobjDescP->objName.pathName[0] != '\0' ? BSAobjDescP->objName.pathName : "",
2257            BSAobjDescP->objectType,
2258            BSAobjDescP->size.left,
2259            BSAobjDescP->size.right,
2260            BSAobjDescP->resourceType[0] != '\0' ?  BSAobjDescP->resourceType : "" ,
2261            BSAdataBlockP->bufferLen,
2262            BSAdataBlockP->numBytes);
2263   }
2264   else
2265   {
2266     if (BSAobjDescP == NULL)
2267       {
2268          bsaRC = BSA_RC_NULL_POINTER;
2269          XOPENRETURN(BSAHandle, "BSACreateObject",
2270                   bsaRC,__FILE__,__LINE__);
2271       }
2272     sprintf(traceStr2, "BSACreateObject ENTRY: BSAHandle:%d", BSAHandle);
2273   }
2274
2275   ourTrace(BSAHandle, TrFL, traceStr2);
2276
2277    xopenGbl.oper = OPER_SEND_START;    /* save state for EndData later */
2278    /*=================================================================
2279    if (BSAobjDescP->version != ObjectDescriptorVersion)
2280        BSA spec doesn't require this currently..
2281    =================================================================*/
2282
2283    /*===============================================================
2284     if the node name is different - we won't create it compare both
2285     the value passed on the BSAInit and the final value used for the
2286     session (which may be different for Generate)
2287     ===============================================================*/
2288    strcpy(upperNode, BSAobjDescP->Owner.bsaObjectOwner);
2289    StrUpper(upperNode);
2290    if ((strcmp(upperNode, xopenGbl.dsmSessInfo.id)) &&
2291       (strcmp(BSAobjDescP->Owner.bsaObjectOwner, xopenGbl.bsaObjectOwner)))
2292    {
2293       sprintf(traceStr2,
2294              "BSACreateObject: BSAObjectOwner(%s) doesn't match value for session(%s).",
2295               upperNode, xopenGbl.dsmSessInfo.id);
2296       ourTrace(BSAHandle,TrFL, traceStr2);
2297       bsaRC = ADSM_RC_INVALID_NODE;
2298       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2299       ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2300       XOPENRETURN(BSAHandle, "BSACreateObject",
2301                   bsaRC,__FILE__,__LINE__);
2302    }
2303
2304    /*=== check string lengths - if this too long, it won't fit in our objInfo ===*/
2305    if (strlen(BSAobjDescP->desc) > ADSM_MAX_DESC)
2306    {
2307       sprintf(traceStr2,"BSACreateObject: description longer than TSM max (%d). ",
2308               strlen(BSAobjDescP->desc));
2309       ourTrace(BSAHandle, TrFL, traceStr2);
2310       bsaRC = BSA_RC_DESC_TOO_LONG;
2311       XOPENRETURN(BSAHandle, "BSACreateObject",
2312                   bsaRC,__FILE__,__LINE__);
2313    }
2314    if (strlen(BSAobjDescP->objectInfo) > ADSM_MAX_OBJINFO)
2315    {
2316       sprintf(traceStr2,"BSACreateObject: objInfo longer than TSM max (%d).",
2317       strlen(BSAobjDescP->objectInfo));
2318       ourTrace(BSAHandle,TrFL, traceStr2);
2319       bsaRC = BSA_RC_OBJINFO_TOO_LONG;
2320       XOPENRETURN(BSAHandle, "BSACreateObject",
2321                   bsaRC,__FILE__,__LINE__);
2322    }
2323
2324    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2325    {
2326       sprintf(traceStr2, "BSACreateObject issued without BSABeginTxn");
2327       ourTrace(BSAHandle,TrFL, traceStr2);
2328       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2329       XOPENRETURN(BSAHandle, "BSACreateObject",
2330                   bsaRC,__FILE__,__LINE__);
2331    }
2332
2333    if (strlen(BSAobjDescP->objName.objectSpaceName) > BSA_MAX_OSNAME)
2334    {
2335       sprintf(traceStr2, "BSACreateObject: objectSpaceName too long (%d)",
2336                        strlen(BSAobjDescP->objName.objectSpaceName));
2337       ourTrace(BSAHandle, TrFL, traceStr2);
2338       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2339       XOPENRETURN(BSAHandle, "BSACreateObject:",
2340                   bsaRC,__FILE__,__LINE__);
2341    }
2342
2343    if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))        /* first CreateObj */
2344    { /* can't issue RegisterFS if already in Txn */
2345       /*=== Register the file space ===*/
2346       regFilespace.stVersion = regFSDataVersion ;
2347       regFilespace.fsName = BSAobjDescP->objName.objectSpaceName ;
2348
2349       /*===  use resource type for fsType (as it was intended)  ===*/
2350
2351       regFilespace.fsType = BSAobjDescP->resourceType ;
2352       regFilespace.capacity.lo = 0;
2353       regFilespace.capacity.hi = 0;
2354       regFilespace.occupancy.lo = 0;
2355       regFilespace.occupancy.hi = 0;
2356       #if _OPSYS_TYPE == DS_AIX
2357          regFilespace.fsAttr.unixFSAttr.fsInfoLength = strlen(XAPI_FSINFO) ;
2358          strcpy(regFilespace.fsAttr.unixFSAttr.fsInfo, XAPI_FSINFO);
2359       #else
2360          regFilespace.fsAttr.dosFSAttr.fsInfoLength = strlen(XAPI_FSINFO) ;
2361          strcpy(regFilespace.fsAttr.dosFSAttr.fsInfo, XAPI_FSINFO);
2362          regFilespace.fsAttr.dosFSAttr.driveLetter = 'X';
2363       #endif
2364       rc = AFSdsmRegisterFS(dsmHandle, &regFilespace) ;
2365       if ((rc != 0) && (rc != DSM_RC_FS_ALREADY_REGED))
2366       {
2367          sprintf(traceStr2, "BSACreateObject(AFSdsmRegisterFS) error rc = %d",rc);
2368          ourTrace(BSAHandle,TrFL, traceStr2);
2369
2370          xlateRC(BSAHandle, rc, &bsaRC);
2371          XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmRegisterFS)",
2372                      bsaRC,__FILE__,__LINE__);
2373       }
2374    }
2375
2376    /*========================================================
2377     Check for invalid copyType before sending data. Log error
2378     to dsirror.log file.
2379     ========================================================*/
2380     if (BSAobjDescP->copyType == BSACopyType_ARCHIVE)
2381        sendType = stArchiveMountWait;
2382     else
2383        if (BSAobjDescP->copyType == BSACopyType_BACKUP)
2384           sendType = stBackupMountWait;
2385        else
2386        {
2387            sprintf(traceStr2,
2388                   "BSACreateObject: invalid copyType (%d)",
2389                    BSAobjDescP->copyType);
2390            ourTrace(BSAHandle,TrFL, traceStr2);
2391            bsaRC = ADSM_RC_INVALID_COPYTYPE;
2392            strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2393            ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2394            XOPENRETURN(BSAHandle, "BSACreateObject",
2395                        bsaRC,__FILE__,__LINE__);
2396        }
2397
2398    if ((BSAobjDescP->objectType == BSAObjectType_FILE) ||
2399       (BSAobjDescP->objectType == BSAObjectType_DATABASE) ||
2400       (BSAobjDescP->objectType == BSAObjectType_ANY))
2401
2402          dsmObjType = DSM_OBJ_FILE;
2403    else
2404       if (BSAobjDescP->objectType == BSAObjectType_DIRECTORY)
2405          dsmObjType = DSM_OBJ_DIRECTORY;
2406       else
2407       {
2408          sprintf(traceStr2,
2409                "BSACreateObject: invalid objectType (%d)",
2410                 BSAobjDescP->objectType);
2411          ourTrace(BSAHandle,TrFL, traceStr2);
2412          bsaRC = ADSM_RC_INVALID_OBJTYPE;
2413          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2414          ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2415          XOPENRETURN(BSAHandle, "BSACreateObject",
2416                     bsaRC,__FILE__,__LINE__);
2417       }
2418
2419    /*==================================================================
2420     put in a check here - count the number of objects per txn
2421     and compare with xopenGbl.sessInfo.maxObjPerTxn
2422     If reach the limit, EndTxn and start a new one
2423     OK to do this without telling the BSA caller?
2424     Or should we exit with an error to tell them the limit is reached ?
2425     ==================================================================*/
2426
2427     if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))
2428     {
2429       rc = AFSdsmBeginTxn(dsmHandle);
2430
2431       if (rc)
2432       {
2433          sprintf(traceStr2, "BSACreateObject(AFSdsmBeginTxn) error rc = %d", rc);
2434          ourTrace(BSAHandle,TrFL, traceStr2);
2435          xlateRC(BSAHandle, rc, &bsaRC);
2436          XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmBeginTxn)",
2437                      bsaRC,__FILE__,__LINE__);
2438       }
2439       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2440     }
2441
2442     /*=== Backup the data  ===*/
2443
2444    /*================================================================
2445      the entire pathname gets copied into hl during parsing, so
2446      check for that max len as well. For now these are the same value.
2447      =================================================================*/
2448    if (strlen(BSAobjDescP->objName.pathName) >
2449             min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
2450    {
2451       sprintf(traceStr2, "BSACreateObject: pathName too long (%d)",
2452               strlen(BSAobjDescP->objName.pathName));
2453       ourTrace(BSAHandle,TrFL, traceStr2);
2454       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2455       XOPENRETURN(BSAHandle, "BSACreateObject",
2456                   bsaRC,__FILE__,__LINE__);
2457    }
2458
2459    strcpy(objName.fs,BSAobjDescP->objName.objectSpaceName) ;
2460    /*=== previous code to use only ll field ===*/
2461    /*objName.hl[0] = '\0';
2462      strcpy(objName.ll,BSAobjDescP->objName.pathName) ;
2463    */
2464    xparsePath(BSAHandle, BSAobjDescP->objName.pathName, objName.hl, objName.ll);
2465    objName.objType = dsmObjType ;
2466
2467    objAttrArea.stVersion = ObjAttrVersion ;
2468    strcpy(objAttrArea.owner,BSAobjDescP->Owner.appObjectOwner);
2469    objAttrArea.sizeEstimate.hi = BSAobjDescP->size.left;
2470    objAttrArea.sizeEstimate.lo = BSAobjDescP->size.right;
2471    objAttrArea.objCompressed = bFalse ;  /* let COMPRESSION option decide */
2472    /*=== whether there's actually compression ===*/
2473    objAttrArea.objInfoLength = sizeof(XAPIObjInfo);
2474    objAttrArea.objInfo = (char *)&xapiObjInfo ;
2475
2476    memset(&xapiObjInfo,0x00,sizeof(XAPIObjInfo));
2477    strcpy(xapiObjInfo.resourceType, BSAobjDescP->resourceType);
2478    xapiObjInfo.size.left = BSAobjDescP->size.left;
2479    xapiObjInfo.size.right = BSAobjDescP->size.right;
2480    strcpy(xapiObjInfo.partDesc, BSAobjDescP->desc);
2481    strcpy(xapiObjInfo.partObjInfo, BSAobjDescP->objectInfo);
2482
2483    /*=== check if a lifecycle group name was passed to us ===*/
2484    if (strlen(BSAobjDescP->lGName))
2485       objAttrArea.mcNameP = (char *)BSAobjDescP->lGName ;
2486    else
2487       objAttrArea.mcNameP = NULL;
2488
2489       dataBlkArea.stVersion = DataBlkVersion ;
2490       if (BSAdataBlockP == NULL)
2491       {
2492          dataBlkArea.bufferPtr = NULL;
2493          dataBlkArea.bufferLen = 0;
2494       }
2495       else
2496       {
2497          dataBlkArea.bufferPtr = BSAdataBlockP->bufferPtr ;
2498          dataBlkArea.bufferLen = BSAdataBlockP->bufferLen;
2499       }
2500
2501       /*=======================================================
2502        always issue BindMC because we don't expect applications
2503        to call ResolveLifecycleGroup since it isn't in the
2504        Data Movement subset
2505        =======================================================*/
2506        mcBindKey.stVersion = mcBindKeyVersion ;
2507        rc = AFSdsmBindMC(dsmHandle, &objName, sendType, &mcBindKey);
2508        if (rc)
2509        {
2510           sprintf(traceStr2, "BSACreateObject(AFSdsmBindMC): error rc = %d", rc);
2511           ourTrace(BSAHandle, TrFL, traceStr2);
2512           xlateRC(BSAHandle, rc, &bsaRC);
2513           XOPENRETURN(BSAHandle, "BSACreateObject(dsnBindMC)",
2514                       bsaRC,__FILE__,__LINE__);
2515        }
2516
2517        /*=== now update state since we'll issue the base Send call ===*/
2518
2519        xopenGbl.oper = OPER_SEND_ISSUED;    /* save state for EndData later */
2520
2521        switch (sendType)
2522        {
2523           case (stBackupMountWait) :
2524           rc = AFSdsmSendObj(dsmHandle,
2525                           sendType,
2526                           NULL,
2527                           &objName,
2528                           &objAttrArea,
2529                           &dataBlkArea);
2530           break;
2531
2532           case (stArchiveMountWait) :
2533           archData.stVersion = sndArchiveDataVersion;
2534           archData.descr = (char *)(BSAobjDescP->desc);
2535           rc = AFSdsmSendObj(dsmHandle,
2536                           sendType,
2537                           &archData,
2538                           &objName,
2539                           &objAttrArea,
2540                           &dataBlkArea);
2541           break;
2542           default : ;
2543        }
2544
2545        if (rc != DSM_RC_OK)
2546        {
2547           sprintf(traceStr2, "BSACreateObject(AFSdsmSendObj) error rc = %d", rc);
2548           ourTrace(BSAHandle,TrFL, traceStr2);
2549
2550           if (rc == DSM_RC_WILL_ABORT)  /* save flag */
2551              xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_RC_WILL_ABORT);
2552
2553           xlateRC(BSAHandle, rc, &bsaRC);
2554           XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmSendObj)",
2555                       bsaRC,__FILE__,__LINE__);
2556        }
2557    XOPENRETURN(BSAHandle, "BSACreateObject",
2558                BSA_RC_SUCCESS, __FILE__,__LINE__);
2559 }
2560
2561
2562 BSA_Int16 BSADeleteObject(
2563     long           BSAHandle,
2564     CopyType       copyType,
2565     ObjectName     *BSAobjNameP,
2566     CopyId         *copyidP
2567 )
2568 {
2569    dsInt16_t      rc = 0;
2570    BSA_Int16      bsaRC = 0;
2571    dsUint32_t     dsmHandle;
2572    dsUint16_t     reason ;                   /* for AFSdsmEndTxn */
2573    dsmObjName     dsmobjName;
2574
2575    dsmDelType delType;
2576    dsmDelInfo delInfo;
2577
2578    delList *llHeadP = NULL;
2579    delList *llTailP = NULL;
2580    delList *ll = NULL;
2581
2582    char errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
2583    char ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
2584
2585    if(!dsm_init)
2586    {
2587 #ifdef DEBUG_BUTC
2588         printf("TSM library not mounted. \n");
2589 #endif
2590         if (dsm_MountLibrary())
2591         {
2592                 printf("TSM Library initialisation failed. \n");
2593                 return 1 ;
2594         }
2595 #ifdef DEBUG_BUTC
2596         printf("TSM Library initialisation SUCCESS. \n");
2597 #endif
2598    }
2599
2600    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2601    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2602
2603    dsmHandle = BSAHandle;
2604
2605    sprintf(traceStr2, "BSADeleteObject ENTRY: BSAHandle:%d CopyType:%d \n ObjName:'%.*s%.*s' copyidP:'%d %d'.",
2606            BSAHandle,
2607            copyType,
2608            100,BSAobjNameP->objectSpaceName,
2609            100,BSAobjNameP->pathName,
2610            copyidP->left,
2611            copyidP->right);
2612    ourTrace(BSAHandle, TrFL, traceStr2);
2613    if (copyType != BSACopyType_ARCHIVE)
2614    {
2615       sprintf(traceStr2,
2616               "BSADeleteObject: invalid copyType %d",
2617                copyType);
2618       ourTrace(BSAHandle,TrFL, traceStr2);
2619       bsaRC = ADSM_RC_INVALID_COPYTYPE;
2620       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2621       ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
2622       XOPENRETURN(BSAHandle, "BSADeleteObject",
2623                   bsaRC,__FILE__,__LINE__);
2624    }
2625
2626    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2627    {
2628       sprintf(traceStr2, "BSADeleteObject issued without BSABeginTxn");
2629       ourTrace(BSAHandle, TrFL, traceStr2);
2630
2631       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2632       XOPENRETURN(BSAHandle, "BSADeleteObject:",
2633                   bsaRC,__FILE__,__LINE__);
2634    }
2635
2636    strcpy(dsmobjName.fs, BSAobjNameP->objectSpaceName);
2637    xparsePath(BSAHandle, BSAobjNameP->pathName, dsmobjName.hl, dsmobjName.ll);
2638    dsmobjName.objType = DSM_OBJ_FILE;
2639
2640    if (!copyidP)    /* NULL, so query and delete all with same name */
2641    {
2642       if (xopenGbl.sessFlags & FL_IN_DSM_TXN)
2643       /*=== if a trxn had been started, end it before doing Query ===*/
2644       {
2645          rc = AFSdsmEndTxn(dsmHandle, DSM_VOTE_COMMIT, &reason);
2646          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
2647       }
2648       rc = buildList(dsmHandle, &dsmobjName, &llHeadP, &llTailP);
2649       if (rc)
2650       {
2651          bsaRC = BSA_RC_OBJECT_NOT_FOUND;
2652          XOPENRETURN(BSAHandle, "BSADeleteObject(buildList)",
2653                      bsaRC,__FILE__,__LINE__);
2654       }
2655    }
2656
2657    if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))        /* first call */
2658    {
2659       rc = AFSdsmBeginTxn(dsmHandle);
2660       if (rc)
2661       {
2662          xlateRC(BSAHandle, rc, &bsaRC);
2663          XOPENRETURN(dsmHandle,"BSADeleteObject(AFSdsmBeginTxn)",
2664                      bsaRC,__FILE__,__LINE__);
2665       }
2666       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2667    }
2668
2669    delType = dtArchive;
2670    delInfo.archInfo.stVersion = delArchVersion;
2671
2672    if (copyidP)   /* single ID to delete */
2673    {
2674       delInfo.archInfo.objId.hi  = copyidP->left;
2675       delInfo.archInfo.objId.lo  = copyidP->right;
2676
2677       if ((rc = AFSdsmDeleteObj(dsmHandle,delType,delInfo)) != DSM_RC_OK)
2678       {
2679          sprintf(traceStr2, "BSADeleteObject: AFSdsmDeleteObj error rc = %d", rc);
2680          ourTrace(dsmHandle,TrFL, traceStr2);
2681       }
2682    }
2683    else   /* multiple IDs to delete */
2684    {
2685       ll = llHeadP;
2686       while (ll)
2687       {
2688          delInfo.archInfo.objId.hi  = ll->objId.hi;
2689          delInfo.archInfo.objId.lo  = ll->objId.lo;
2690          if ((rc = AFSdsmDeleteObj(dsmHandle, delType, delInfo)) != DSM_RC_OK)
2691          {
2692             sprintf(traceStr2, "BSADeleteObject: AFSdsmDeleteObj error rc = %d", rc);
2693             ourTrace(dsmHandle, TrFL, traceStr2);
2694             /*=== break and get out of loop, or keep going? ===*/
2695          }
2696          /*=== incr to next list entry ===*/
2697          ll = ll->next;
2698       }
2699       /*=== free list now that done ===*/
2700       rc =  freeList(&llHeadP, &llTailP);
2701    }
2702
2703    xlateRC(BSAHandle, rc, &bsaRC);
2704    XOPENRETURN(BSAHandle,"BSADeleteObject",
2705                bsaRC,__FILE__,__LINE__)
2706 }
2707
2708 BSA_Int16 BSAMarkObjectInactive(
2709     long            BSAHandle,
2710     ObjectName     *BSAobjNameP
2711 )
2712 {
2713    dsInt16_t      rc = 0;
2714    BSA_Int16      bsaRC = 0;
2715    dsUint32_t     dsmHandle;
2716
2717    dsmObjName           dsmobjName;
2718
2719    qryBackupData        queryBuffer;       /* for query Backup */
2720    qryRespBackupData    qbDataArea;
2721    DataBlk              qDataBlkArea;
2722
2723    dsmDelType           delType;
2724    dsmDelInfo           delInfo;
2725
2726    dsUint16_t           reason ;                   /* for AFSdsmEndTxn */
2727    /*=== build list of all objTypes we find for this name ===*/
2728    dsInt16_t            i;
2729    dsInt16_t            numTypes;
2730    dsUint8_t            listObjType[5];    /* only 2 objTypes defined today */
2731    dsUint32_t           listCopyGroup[5];
2732
2733    if(!dsm_init)
2734    {
2735 #ifdef DEBUG_BUTC
2736         printf("TSM library not mounted. \n");
2737 #endif
2738         if (dsm_MountLibrary())
2739         {
2740                 printf("TSM Library initialisation failed. \n");
2741                 return 1 ;
2742         }
2743 #ifdef DEBUG_BUTC
2744         printf("TSM Library initialisation SUCCESS. \n");
2745 #endif
2746    }
2747
2748    dsmHandle = BSAHandle;
2749    memset(&delInfo, 0x00, sizeof(dsmDelInfo));
2750    memset(&queryBuffer, 0x00, sizeof(qryBackupData));
2751
2752    sprintf(traceStr2, "BSAMarkObjectInactive ENTRY: BSAHandle:%d \n ObjName:'%.*s%.*s'.",
2753            BSAHandle,
2754            100, BSAobjNameP->objectSpaceName,
2755            100, BSAobjNameP->pathName);
2756    ourTrace(dsmHandle, TrFL, traceStr2);
2757
2758    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2759    {
2760       sprintf(traceStr2, "BSAMarkObjectInactive: issued without BSABeginTxn.");
2761       ourTrace(BSAHandle, TrFL, traceStr2);
2762       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2763       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2764                   bsaRC,__FILE__,__LINE__);
2765    }
2766
2767    if (strlen(BSAobjNameP->objectSpaceName) > DSM_MAX_FSNAME_LENGTH)
2768    {
2769       sprintf(traceStr2, "BSAMarkObjectInactive: objectSpaceName too long (%d)", strlen(BSAobjNameP->objectSpaceName));
2770       ourTrace(BSAHandle,TrFL, traceStr2);
2771
2772       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2773       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2774                   bsaRC,__FILE__,__LINE__);
2775    }
2776    /*===============================================================
2777     The entire pathname gets copied into hl during parsing, so
2778     check for that max len as well. For now these are the same value.
2779     =============================================================== */
2780    if (strlen(BSAobjNameP->pathName) >
2781        min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
2782    {
2783       sprintf(traceStr2, "BSAMarkObjectInactive: pathName too long (%d)",
2784                          strlen(BSAobjNameP->pathName));
2785       ourTrace(BSAHandle,TrFL, traceStr2);
2786       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2787       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2788                   bsaRC,__FILE__,__LINE__);
2789    }
2790
2791    /*==============================================================
2792     we don't allow any wildcard in name because that could retrieve
2793     LOTS of objects and make list processing more complicated.
2794     XBSA spec implies a single object.
2795     ==============================================================*/
2796    if ( strchr(BSAobjNameP->objectSpaceName, '*') ||
2797         strchr(BSAobjNameP->objectSpaceName, '?') ||
2798         strchr(BSAobjNameP->pathName,        '*') ||
2799         strchr(BSAobjNameP->pathName,        '?'))
2800    {
2801
2802       sprintf(traceStr2, "BSAMarkObjectInactive: objName contains a wildcard.")
2803 ;
2804       ourTrace(BSAHandle, TrFL, traceStr2);
2805       /*=== could have a more specific rc, use this for now ===*/
2806       bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2807       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2808                   bsaRC,__FILE__,__LINE__);
2809    }
2810
2811    strcpy(dsmobjName.fs, BSAobjNameP->objectSpaceName);
2812    xparsePath(BSAHandle, BSAobjNameP->pathName, dsmobjName.hl, dsmobjName.ll);
2813    dsmobjName.objType = DSM_OBJ_ANY_TYPE;
2814
2815    /*============================================================
2816     A Backup Delete must include the copy Group and objType this
2817     wasn't passed in, so we have to do a query.
2818     ============================================================*/
2819
2820    queryBuffer.stVersion = qryBackupDataVersion ;
2821    queryBuffer.objName = &dsmobjName;
2822    queryBuffer.owner   = xopenGbl.dsmSessInfo.owner;
2823    queryBuffer.objState = DSM_ACTIVE;              /* only get active one */
2824
2825    if ((rc=AFSdsmBeginQuery(dsmHandle, qtBackup,
2826                         (void *)&queryBuffer )) != DSM_RC_OK)
2827    {
2828       sprintf(traceStr2, "BSAMarkObjectInactive: Call to AFSdsmBeginQuery for Backup error rc = %d", rc);
2829       ourTrace(BSAHandle,TrFL, traceStr2);
2830       xlateRC(BSAHandle, rc, &bsaRC);
2831       if ((rc == DSM_RC_ABORT_NO_MATCH) ||    /* special rc for MarkInact */
2832           (rc == DSM_RC_FILE_SPACE_NOT_FOUND))
2833          bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2834
2835       rc = AFSdsmEndQuery(dsmHandle);
2836       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive: AFSdsmBeginQuery",
2837                   bsaRC,__FILE__,__LINE__);
2838    }
2839
2840    qbDataArea.stVersion   = qryRespBackupDataVersion;
2841    qDataBlkArea.stVersion = DataBlkVersion ;
2842    qDataBlkArea.bufferPtr = (char *)&qbDataArea;
2843    qDataBlkArea.bufferLen = sizeof(qryRespBackupData);
2844
2845    numTypes = 0;
2846    rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea);
2847    while (((rc == DSM_RC_MORE_DATA) ||
2848          (rc == DSM_RC_FINISHED)) &&
2849           qDataBlkArea.numBytes)
2850    {  /* save copy Group we got */
2851       listCopyGroup[numTypes] = qbDataArea.copyGroup;
2852       listObjType[numTypes]   = qbDataArea.objName.objType;
2853       numTypes++;
2854       rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea);
2855    }
2856
2857    if (rc != DSM_RC_FINISHED)
2858    {
2859       xlateRC(BSAHandle, rc, &bsaRC);
2860       if ((rc == DSM_RC_ABORT_NO_MATCH) || /* special rc for MarkInact */
2861           (rc == DSM_RC_FILE_SPACE_NOT_FOUND))
2862          bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2863       rc = AFSdsmEndQuery(dsmHandle);
2864       XOPENRETURN(BSAHandle,"BSAMarkObjectInactive: AFSdsmGetNextQObj",
2865                   bsaRC,__FILE__,__LINE__);
2866    }
2867    rc = AFSdsmEndQuery(dsmHandle);
2868
2869    /*=== now we can do the delete ===*/
2870    rc = AFSdsmBeginTxn(dsmHandle);
2871
2872    if (rc)
2873    {
2874      xlateRC(BSAHandle, rc, &bsaRC);
2875      XOPENRETURN(BSAHandle,"BSAMarkObjectInactive: AFSdsmBeginTxn",
2876                  bsaRC,__FILE__,__LINE__);
2877    }
2878    xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2879
2880    delType = dtBackup;     /* this only applies to Backup */
2881
2882    delInfo.backInfo.stVersion = delBackVersion;
2883    delInfo.backInfo.objNameP = &dsmobjName;
2884
2885    for (i=0; i<numTypes; i++)
2886    {
2887       delInfo.backInfo.copyGroup = listCopyGroup[i];
2888       dsmobjName.objType         = listObjType[i];
2889
2890       if ((rc = AFSdsmDeleteObj(dsmHandle, delType, delInfo)) != DSM_RC_OK)
2891       {
2892
2893          sprintf(traceStr2, "BSAMarkObjectInactive: call to AFSdsmDeleteObj error rc = %d", rc);
2894          ourTrace(BSAHandle, TrFL, traceStr2);
2895       }
2896    }
2897
2898    /*=== issue EndTxn since these can't be nested because of Query sequence ===*/
2899    AFSdsmEndTxn(dsmHandle, DSM_VOTE_COMMIT, &reason);
2900    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
2901
2902    xlateRC(BSAHandle, rc, &bsaRC);
2903    XOPENRETURN(BSAHandle,"BSAMarkObjectInactive",
2904                bsaRC,__FILE__,__LINE__);
2905 }
2906
2907 #endif /*xbsa*/