Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/RawAPI/rawCliProcn.c

Go to the documentation of this file.
00001 //---------------------------------------------------------------
00002 //        Go4 Release Package v2.10-5 (build 21005) 
00003 //                      03-Nov-2005
00004 //---------------------------------------------------------------
00005 //       The GSI Online Offline Object Oriented (Go4) Project
00006 //       Experiment Data Processing at DVEE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 /**********************************************************************
00017  * Copyright:
00018  *   GSI, Gesellschaft fuer Schwerionenforschung mbH
00019  *   Planckstr. 1
00020  *   D-64291 Darmstadt
00021  *   Germany
00022  * created 28. 8.1996 by Horst Goeringer
00023  **********************************************************************
00024  * rawCliProcn.c:
00025  *    utility programs for GSI mass storage: clients only
00026  *    new version
00027  **********************************************************************
00028  * rawCheckFilelist: remove objects already archived from file list
00029  * rawCheckObjlist:  remove existing files from object and file list,
00030  *                   reorder according to restore parameter
00031  * rawDelFile:     delete single file in GSI mass storage
00032  * rawDelList:     delete list of files in GSI mass storage
00033  * rawGetFilelistEntries: get filelist entries from input file
00034  * rawGetWSInfo:   get workspace and pool info from master
00035  * rawQueryFile:   get query information for single file
00036  * rawQueryList:   get query information from list of files
00037  * rawScanObjbuf:  check if obj already available in obj buffer chain
00038  * ielpst:         AIX only: elapsed (wall-clock) time measurement
00039  **********************************************************************
00040  * 26. 3.1996, H.G.: rawCheckObjlist: work on ptr-linked object buffers
00041  * 21.11.1997, H.G.: rawDelFile: only warning (rc=1) if obj not found
00042  * 19.12.2000, H.G.: rawCheckObjlist: remove unused code, better doc
00043  * 21. 2.2001, H.G.: renamed file rawQueryFile.c -> rawProcQuery.c
00044  *                   function rawQueryList added
00045  * 18. 5.2001, H.G.: merge into new file rawcliproc.c:
00046  *                   rawProcQuery.c
00047  *                   rawDelFile.c
00048  *                   rawDelList (rawDelFilelist from rawproc.c)
00049  *                   rawTapeFile.c
00050  *                   ielpst.c
00051  * 20. 7.2001, H.G.: rawCheckObjlist: mover node in srawRetrList
00052  * 24. 8.2001, H.G.: rawCheckObjlist: stage status in srawRetrList
00053  * 24. 1.2002, H.G.: created from rawcliproc.c, ACTION DELETE -> REMOVE
00054  * 13. 2.2002, H.G.: rawDelFile: handle also stage file
00055  * 25. 4.2002, H.G.: move rawTapeFile to new file rawProcTape.c
00056  *  5. 8.2002, H.G.: rawQueryFile: handle QUERY_RETRIEVE, QUERY_STAGE
00057  * 13. 1.2003, H.G.: rawCheckFilelist: reset cFilell before calling
00058  *                   rawGetLLName
00059  * 31. 1.2003, H.G.: use rawdefn.h
00060  *  4. 2.2003, H.G.: rawDelList, obj list: srawArchList -> srawRetrList
00061  *                   rawCheckFilelist, obj list: change type from
00062  *                   srawArchList -> srawRetrList
00063  * 14. 2.2003, H.G.: rawDelList: handles list of data movers
00064  *                   rawCheckFilelist: new arg pcNodeMaster
00065  * 17. 2.2003, H.G.: rawCheckFilelist, rawCheckObjlist from rawprocn.c
00066  * 17. 2.2003, H.G.: rawCheckFilelist: return in filelist ptr
00067  * 22. 5.2003, H.G.: renamed to rawCliProcn.c, new rawGetFilelistEntries
00068  * 27. 6.2003, H.G.: new function rawGetWSInfo
00069  * 18. 7.2003, H.G.: handle action QUERY_RETRIEVE_API
00070  * 23. 2.2004, H.G.: rawCheckObjlist: StageFS, ArchiveFS in srawRetrList
00071  *  5. 3.2004, H.G.: rawCheckObjlist: cArchiveDate, cOwner in srawRetrList
00072  **********************************************************************
00073  */
00074 
00075 #include <stdio.h>
00076 #include <string.h>
00077 #include <sys/socket.h>
00078 #include <time.h>
00079 
00080 #ifdef Linux
00081 #include <linux/in.h>
00082 #endif
00083 
00084 #include "rawapitd.h"
00085 #include "rawapitd-gsi.h"
00086 #include "rawcommn.h"
00087 #include "rawdefn.h"
00088 #include "rawclin.h"
00089 #include "rawentn.h"
00090 #include "rawapplcli.h"
00091 
00092 extern FILE *fLogFile;
00093 extern int *piEntryList;                /* for rawGetFilelistEntries */
00094 
00095 static int iqueryMax = 0;       /* max no. of files per query buffer */
00096 static int iQueryCount = 0;            /* overall no. of files found */
00097 static char *pQueryBuffer;                /* pointer to query buffer */
00098 static srawQueryResult *pQueryResult;
00099 static srawObjAttr *pQueryObj, *pQueryObj0;
00100 
00101 /********************************************************************
00102  * rawCheckFilelist: remove objects already archived from file list
00103  *    returns number of removed objects
00104  *
00105  * created 15. 3.96, Horst Goeringer
00106  * 25. 3.1996, H.G.: work on ptr-linked object buffers
00107  ********************************************************************
00108  */
00109 
00110 int rawCheckFilelist(char **pcFileList, char **pcObjList,
00111                      char *pcNodeMaster)
00112 {
00113    char cModule[32] = "rawCheckFilelist";
00114    int iDebug = 0;
00115 
00116    char cDelimiter[1] = "";
00117    char *pcfl, *pcol;
00118    int *pifl, *piol;
00119    int ifile0, ifile;
00120    int iobj0, iobj, iobjf = 0;
00121 
00122    srawArchList *psFile, *psFile0;        /* files to be archived */
00123    srawRetrList *psObj, *psObj0;      /* objects already archived */
00124 
00125    char cFilell[MAX_OBJ_LL];
00126    char *pcFilell;             /* temp obj ll name from file name */
00127 
00128    bool_t bLastBuf;
00129    int iobjBuf;
00130    int **piptr;               /* points to pointer to next buffer */
00131    int *pinext;               /* points to next buffer */
00132 
00133    int ii, jj, iif;
00134    int iRC, idel;
00135 
00136    pcfl = *pcFileList;
00137    pifl = (int *) pcfl;
00138    ifile0 = pifl[0];                   /* initial number of files */
00139    ifile = ifile0;
00140    psFile = (srawArchList *) ++pifl;  /* points now to first file */
00141    psFile0 = psFile;
00142    pifl--;                     /* points again to number of files */
00143 
00144    pcol = *pcObjList;
00145    piol = (int *) pcol;
00146    iobj0 = piol[0];                  /* number of archived objects */
00147    iobj = iobj0;
00148    psObj = (srawRetrList *) ++piol;  /* points now to first object */
00149    psObj0 = psObj;
00150    piol--;                    /* points again to number of objects */
00151 
00152    pcFilell = cFilell;
00153 
00154    if (iDebug)
00155    {
00156       fprintf(fLogFile,
00157          "\n-D- begin %s: initial %d files, %d objects (1st buffer)\n",
00158          cModule, ifile0, iobj0);
00159       fprintf(fLogFile, "    first file %s, first obj %s\n",
00160              (char *) psFile, (char *) psObj);
00161    }
00162 
00163    iRC = strncmp( (char *) psObj, pcObjDelim, 1);
00164    if (iRC)
00165    {
00166       iRC = strncmp( (char *) psObj, pcObjDelimAlt, 1);
00167       if (iRC)
00168       {
00169          fprintf(fLogFile,
00170                 "-E- %s: invalid object delimiter %1s found\n",
00171                 cModule, (char *) psObj);
00172          return -1;
00173       }
00174       else
00175          strcpy(cDelimiter, pcObjDelimAlt);
00176    }
00177    else
00178       strcpy(cDelimiter, pcObjDelim);
00179 
00180    for (ii = 1; ii <= ifile0; ii++)                     /* file loop */
00181    {
00182       psObj = psObj0;                          /* first object again */
00183       iobj = iobj0;                     /* first object number again */
00184       strcpy(cFilell, "");
00185       iRC = rawGetLLName( (char *) psFile, cDelimiter, cFilell);
00186 
00187       if (iDebug)
00188          fprintf(fLogFile, "DDD cFilell: |%s|\n", cFilell);
00189 
00190       bLastBuf = bFalse;
00191       iobjBuf = 1;
00192       if (iDebug > 1)
00193          fprintf(fLogFile, "\n*** buffer %d: %d objs\n", iobjBuf, iobj);
00194 
00195       while (!bLastBuf)
00196       {
00197 
00198          for (jj = 1; jj <= iobj; jj++)         /* object loop */
00199          {
00200 
00201             iRC = strcmp(cFilell, (char *) psObj);
00202             if (iRC == 0)                      /* file archived */
00203             {
00204               if (iDebug) fprintf(fLogFile,
00205                  "-E- %s-%d: file %s already archived at specified path\n",
00206                  cModule, ii, ++pcFilell);
00207               else
00208                  fprintf(fLogFile, "-E- file %s already archived at specified path on server %s\n",
00209                         ++pcFilell, pcNodeMaster);
00210                pcFilell--;
00211 
00212                strncpy( (char *) psFile, "\n", 1);
00213                ifile--;
00214                if (ifile == 0)
00215                {
00216                   if (iDebug) fprintf(fLogFile,
00217                       "-D- %s: last file, comparison finished\n",
00218                       cModule);
00219                   goto gEndCompare;
00220                }
00221                goto gNextFile;
00222 
00223             } /* iRC == 0: file already archived */
00224 
00225             psObj++;
00226          } /* object loop */
00227 
00228          piptr = (int **) psObj;
00229          if (*piptr == NULL)
00230          {
00231             bLastBuf = bTrue;
00232             if (iDebug > 1)
00233                fprintf(fLogFile, "    %d: last obj buffer\n", iobjBuf);
00234             if (iDebug)
00235                fprintf(fLogFile, "*** %d: %s (%s) to be archived\n",
00236                       ii, (char *) psFile, cFilell);
00237          }
00238          else
00239          {
00240             iobjBuf++;
00241             pinext = *piptr;
00242             iobj = *pinext++;
00243             psObj = (srawRetrList *) pinext;
00244             if (iDebug > 1) fprintf(fLogFile,
00245                "\n*** new buffer %d: %d objs, first obj %s|\n",
00246                iobjBuf, iobj, (char *) psObj);
00247          }
00248 
00249       } /* while (!bLastBuf) */
00250 
00251 gNextFile:
00252       psFile++;
00253    } /* file loop */
00254 
00255 gEndCompare:
00256    idel = ifile0-ifile;
00257    if (iDebug) fprintf(fLogFile,
00258       "-D- %s: %d of %d files removed: %d remaining\n",
00259       cModule, idel, ifile0, ifile);
00260 
00261    pifl[0] = ifile;
00262    *pcFileList = (char *) pifl;
00263 
00264    if ( (ifile > 0) && (idel > 0) )        /* compress filelist */
00265    {
00266       if (iDebug) fprintf(fLogFile,
00267          "-D- compress file list: search %d files\n", ifile);
00268       iif = 1;
00269       psFile = psFile0;
00270       for (ii = 1; ii <= ifile0; ii++)             /* file loop */
00271       {
00272          /* fprintf(fLogFile, "%d: %s\n", ii, (char *) psFile); */
00273          iRC = strncmp( (char *) psFile, "\n", 1);
00274          if (iRC != 0)                            /* file found */
00275          {
00276             if (iif == ifile0) goto gEndCompress;
00277             psFile0++;
00278             psFile++;
00279             iif++;
00280          }
00281          else
00282          {                                    /* compress action */
00283             for (jj = ii+1; jj <= ifile0; jj++)
00284             {
00285                psFile++;
00286                iif++;
00287                iRC = strncmp( (char *) psFile, "\n", 1);
00288                if (iRC == 0)
00289                {
00290                   if (iif == ifile0) goto gEndCompress;
00291                }
00292                else
00293                {
00294                   strcpy( (char *) psFile0, (char *) psFile);
00295                   if (iDebug > 1) fprintf(fLogFile,
00296                      "*** %d: %s\n", iif, (char *) psFile0);
00297                   if (iif == ifile0) goto gEndCompress;
00298                   psFile0++;
00299                }
00300             } /* for (jj...) */
00301 
00302          } /* compress action */
00303       } /* for (ii...) */
00304    } /* ifile > 0 && idel > 0 */
00305 
00306 gEndCompress:
00307 
00308    if (iDebug)
00309       fprintf(fLogFile, "-D- end %s\n\n", cModule);
00310    return idel ;
00311 
00312 } /* rawCheckFilelist */
00313 
00314 /********************************************************************
00315  * rawCheckObjlist:
00316  *    on input:
00317  *       FileComp: no. of valid files/objs
00318  *       pcObjList: chain of ptr-linked buffers with obj lists
00319  *       pcFileList: corresponding file list (one buffer)
00320  *    on output:
00321  *       pcFileList: compressed and sorted file list
00322  *       pcObjListall: corresponding compressed and sorted obj list
00323  *                     (one buffer)
00324  *    remove files/objs with zero length ll names from both lists,
00325  *    reorder remaining files/objs according to restore parameter
00326  *
00327  * created 18. 3.96, Horst Goeringer
00328  ********************************************************************
00329  */
00330 
00331 int rawCheckObjlist(int iFileComp,
00332                     char **pcObjList,
00333                     char **pcFileList,
00334                     char **pcObjListall)
00335 {
00336    int iDebug = 0;
00337    char cModule[32]="rawCheckObjlist";
00338    int iRC;
00339 
00340    char *pcfl, *pcol, *pcolall;
00341    int  *pifl, *piol;
00342    int ifile0;
00343    int iobj0, iobj;
00344 
00345    char *pcFileBuf, *pcObjBuf;
00346    int iFileBuf, iObjBuf;
00347    int  *piflcopy, *piolcopy;
00348 
00349    int iiObj, iiBuf;
00350    int **piptr;               /* points to pointer to next buffer */
00351    int *pinext;               /* points to next buffer */
00352 
00353    srawArchList *psFile, *psFile0;        /* files to be written   */
00354 
00355    srawRetrList *psObj, *psObj0;        /* objects to be retrieved */
00356    srawRetrList *psObjMin;       /* object with min restore number */
00357 
00358    srawArchList *psFileCopy;              /* files to be written   */
00359    srawRetrList *psObjCopy;             /* objects to be retrieved */
00360 
00361    int ii, jj, jjMin;
00362    int icount;
00363 
00364    unsigned int irestoHLmin, irestoLLmin;
00365    bool_t bInit;
00366 
00367    pcfl = *pcFileList;
00368    pifl = (int *) pcfl;
00369    ifile0 = pifl[0];                       /* number of all files */
00370    psFile = (srawArchList *) ++pifl;  /* points now to first file */
00371    psFile0 = psFile;
00372    pifl--;                     /* points again to number of files */
00373 
00374    pcolall = *pcObjListall;
00375    pcol = *pcObjList;
00376    piol = (int *) pcol;
00377    iobj0 = piol[0];        /* number of archived objects in buffer */
00378    psObj = (srawRetrList *) ++piol;  /* points now to first object */
00379    psObj0 = psObj;
00380    piol--;                    /* points again to number of objects */
00381 
00382    if (iDebug)
00383    {
00384       fprintf(fLogFile,
00385          "\n-D- begin %s: initial %d files, %d objects (1st buffer)\n",
00386          cModule, ifile0, iobj0);
00387       fprintf(fLogFile,
00388          "    compressed: %d files/objects\n", iFileComp);
00389    }
00390    if (iDebug > 1)
00391       fprintf(fLogFile, "    first file %s, first obj %s\n",
00392               (char *) psFile, psObj->cNamell);
00393 
00394    iFileBuf = sizeof(int) + iFileComp*sizeof(srawArchList);
00395    if ((pcFileBuf = (char *) calloc(iFileBuf, sizeof(char) ) ) == NULL)
00396    {
00397       perror("-E- rawCheckObjlist: allocating filelist buffer");
00398       return(-2);
00399    }
00400    if (iDebug) fprintf(fLogFile,
00401       "    filelist buffer allocated for retrieve (size %d)\n",
00402       iFileBuf);
00403 
00404    piflcopy = (int *) pcFileBuf;
00405    piflcopy[0] = iFileComp;           /* compressed number of files */
00406    psFileCopy = (srawArchList *) ++piflcopy;
00407                                       /* points now to first file */
00408 
00409    iObjBuf = sizeof(int) + iFileComp*sizeof(srawRetrList);
00410    if ( ( pcObjBuf = (char *) calloc(iObjBuf, sizeof(char) ) ) == NULL )
00411    {
00412       perror("-E- rawCheckObjlist: allocating objlist buffer");
00413       return(-3);
00414    }
00415    if (iDebug) fprintf(fLogFile,
00416       "    objlist buffer allocated for retrieve (size %d)\n", iObjBuf);
00417 
00418    piolcopy = (int *) pcObjBuf;
00419    piolcopy[0] = iFileComp;           /* compressed number of files */
00420    psObjCopy = (srawRetrList *) ++piolcopy;
00421                                         /* points now to first file */
00422 
00423    iiObj = 0;                   /* no. of objects in current buffer */
00424    iiBuf = 1;                       /* no. of current object buffer */
00425    icount = 0;                      /* no. of files/objects copied  */
00426    for (ii = 1; ii <= iFileComp; ii++)
00427    {                   /* loop over COMPRESSED no. of files/objects */
00428       if (iDebug > 1)
00429          fprintf(fLogFile, "\nDDD object %d:\n", ii);
00430       bInit = bTrue;
00431       iobj = iobj0;         /* no. of arch. objects in first buffer */
00432 
00433       for (jj = 1; jj <= ifile0; jj++)
00434       {                              /* loop over ALL files/objects */
00435          iiObj++;
00436          if (iDebug > 1) fprintf(fLogFile,
00437             "*** buffer %d, obj %d: %s\n",
00438             iiBuf, iiObj, psObj->cNamell);
00439          iRC = strncmp(psObj->cNamell, "\0", 1);
00440          if (iDebug > 1) fprintf(fLogFile,
00441             "DDD %d,%d: %s, iRC %d\n", ii, jj, psObj->cNamell, iRC);
00442          if (iRC != 0)
00443          {
00444             if (bInit)
00445             {
00446                jjMin = jj;
00447                psObjMin  = psObj;            /* default min: 1st obj */
00448                irestoHLmin = psObj->iRestoHigh;
00449                irestoLLmin = psObj->iRestoLow;
00450                bInit = bFalse;
00451                if (iDebug > 1) fprintf(fLogFile,
00452                   "DDD0 new min %s: %d-%d\n", (char *) psObjMin,
00453                   irestoHLmin, irestoLLmin);
00454                if (ii == iFileComp)             /* last file/object */
00455                   goto gStore;
00456             }
00457             if (iDebug > 1) fprintf(fLogFile,
00458                "DDD found: %d-%d\n",
00459                psObj->iRestoHigh, psObj->iRestoLow);
00460             if (psObj->iRestoHigh < irestoHLmin)
00461             {
00462                jjMin = jj;
00463                psObjMin  = psObj;                       /* keep obj */
00464                irestoHLmin = psObj->iRestoHigh;
00465                irestoLLmin = psObj->iRestoLow;
00466                if (iDebug > 1) fprintf(fLogFile,
00467                   "DDD1 new min %s: %d-%d\n", (char *) psObjMin,
00468                   irestoHLmin,
00469                   irestoLLmin);
00470                if (ii == iFileComp)             /* last file/object */
00471                   goto gStore;
00472             }
00473             else
00474             {
00475                if (psObj->iRestoHigh == irestoHLmin)
00476                {
00477                   if (psObj->iRestoLow < irestoLLmin)
00478                   {
00479                      jjMin = jj;
00480                      psObjMin  = psObj;                /* keep obj */
00481                      irestoHLmin = psObj->iRestoHigh;
00482                      irestoLLmin = psObj->iRestoLow;
00483                      if (iDebug > 1) fprintf(fLogFile,
00484                         "DDD2 new min %s: %d-%d\n",
00485                         (char *) psObjMin,
00486                         irestoHLmin,
00487                         irestoLLmin);
00488                      if (ii == iFileComp)      /* last file/object */
00489                         goto gStore;
00490 
00491                   } /* psObj->iRestoLow < irestoLLmin */
00492                } /* psObj->iRestoHigh == irestoHLmin */
00493 
00494             } /* psObj->iRestoHigh >= irestoHLmin */
00495          } /* iRC != 0 */
00496 
00497          psObj++;
00498          if (iiObj == iobj)
00499          {
00500             if (iDebug > 1) fprintf(fLogFile,
00501                "    buffer %d: last obj (no. %d) handled\n",
00502                iiBuf, iiObj);
00503             piptr = (int **) psObj;
00504             if (*piptr == NULL)
00505             {
00506                if (iDebug > 1) fprintf(fLogFile,
00507                   "    %d: last obj buffer\n", iiBuf);
00508             }
00509             else
00510             {
00511                iiObj = 0;
00512                iiBuf++;
00513                pinext = *piptr;
00514                iobj = *pinext++;
00515                psObj = (srawRetrList *) pinext;
00516                if (iDebug > 1) fprintf(fLogFile,
00517                   "    %d: new buffer, %d objs, first: %s|\n",
00518                   iiBuf, iobj, psObj->cNamell);
00519             }
00520 
00521          } /* iiObj == iobj */
00522 
00523 
00524       } /* for (jj...) */
00525 
00526 gStore:
00527       icount++;
00528       psObj = psObjMin;
00529       if (iDebug)
00530       {
00531          fprintf(fLogFile, "-D- copy %d-%d\n",
00532                  irestoHLmin, irestoLLmin);
00533          fprintf(fLogFile, "    obj %s, %d-%d\n", psObj->cNamell,
00534                  psObj->iObjHigh, psObj->iObjLow);
00535       }
00536 
00537       /* write obj items to temp structure */
00538       strcpy(psObjCopy->cNamell, psObj->cNamell);
00539       psObjCopy->iObjHigh = psObj->iObjHigh;
00540       psObjCopy->iObjLow =  psObj->iObjLow;
00541       psObjCopy->iRestoHigh = psObj->iRestoHigh;
00542       psObjCopy->iRestoLow = psObj->iRestoLow;
00543       psObjCopy->iFileType = psObj->iFileType;
00544       psObjCopy->iBufsizeFile = psObj->iBufsizeFile;
00545       psObjCopy->iFileSize = psObj->iFileSize;
00546       psObjCopy->iStageFS = psObj->iStageFS;
00547       strcpy(psObjCopy->cNodeMover, psObj->cNodeMover);
00548       psObjCopy->iArchiveFS = psObj->iArchiveFS;
00549       strcpy(psObjCopy->cArchiveDate, psObj->cArchiveDate);
00550       strcpy(psObjCopy->cOwner, psObj->cOwner);
00551 
00552       strncpy(psObj->cNamell, "\0", 1);      /* make it invalid */
00553 
00554       psFile = psFile0;
00555       psFile += (jjMin-1);
00556       if (iDebug)
00557          fprintf(fLogFile, "    file %s\n", (char *) psFile->cFile);
00558       iRC = strncmp(psFile->cFile, "\0", 1);
00559       if (iRC == 0)
00560       {
00561          fprintf(fLogFile,
00562             "-E- %s: file and object lists inconsistent\n", cModule);
00563          return(-4);
00564       }
00565       else if (iDebug)
00566          fprintf(fLogFile, "    write file %s to temp structure\n",
00567                  (char *) psFile->cFile);
00568 
00569       /* write file to temp structure */
00570       strcpy(psFileCopy->cFile, psFile->cFile);
00571 
00572       strncpy(psFile->cFile, "\0", 1);       /* make it invalid */
00573 
00574       /* set ptrs for next iteration */
00575       psObj = psObj0;
00576       psObjCopy++;
00577       psFile = psFile0;
00578       psFileCopy++;
00579 
00580       iiObj = 0;
00581       iiBuf = 1;
00582 
00583    } /* for (ii..) */
00584 
00585    if (icount != iFileComp)
00586    /* if (iRC != 0) */
00587    {
00588       fprintf(fLogFile,
00589          "-E- %s: unexpected no. of objects (%d) found\n",
00590          cModule, icount);
00591       return -5;
00592    }
00593    else if (iDebug)
00594       fprintf(fLogFile, "    obj no. %d okay\n", icount);
00595 
00596    /* memset(pcol, 0x00, iObjBuf); */
00597    memcpy(pcolall, pcObjBuf, iObjBuf);
00598    memset(pcfl, 0x00, iFileBuf);
00599    memcpy(pcfl, pcFileBuf, iFileBuf);
00600 
00601    if (iDebug) fprintf(fLogFile,
00602       "-D- end %s\n\n", cModule);
00603    return 0;
00604 
00605 } /* rawCheckObjlist */
00606 
00607 /*********************************************************************
00608  * rawDelFile: delete single file in GSI mass storage
00609  *
00610  * created  8.10.1996, Horst Goeringer
00611  *********************************************************************
00612  */
00613 
00614 int rawDelFile( int iSocket,
00615                 srawComm *pCommBuf)
00616 {
00617    int iDebug = 0;
00618    char cModule[32] = "rawDelFile";
00619 
00620    int iStage = 0;
00621    int iRC;
00622    int iIdent;
00623    int iStatus, iStatusLen;
00624    int iBuf, iBufComm;
00625    char *pc, *pBuf;
00626 
00627    srawComm *pComm;
00628    srawStatus sStatus;
00629    srawQueryResult sQuery;
00630    srawObjAttr *pQAttr;
00631 
00632    pComm = pCommBuf;
00633    iBufComm = ntohl(pComm->iCommLen) + HEAD_LEN;
00634    if (iDebug) printf(
00635       "\n-D- begin %s: delete file %s\n", cModule, pComm->cNamell);
00636 
00637    /* make query to get object ids (unavailable in archive lists) */
00638    pBuf = (char *) &sQuery;
00639    pQAttr = &(sQuery.objAttr);
00640    pComm->iAction = htonl(QUERY_REMOVE);
00641    iRC = rawQueryFile(iSocket, pComm, (void *) &pBuf);
00642 
00643    if (iDebug)
00644       printf("    after rawQueryFile, rc = %d\n", iRC);
00645 
00646    if (iRC <= 0)
00647    {
00648       if (iRC < 0)
00649          return iRC;                                /* error occured */
00650 
00651       printf("-W- object %s%s%s not found\n",
00652              pComm->cNamefs, pComm->cNamehl, pComm->cNamell);
00653       return 1;
00654    }
00655 
00656    if ( (ntohl(pQAttr->iMediaClass) == GSI_MEDIA_STAGE) ||
00657         (ntohl(pQAttr->iMediaClass) == GSI_MEDIA_LOCKED) )
00658       iStage = ntohl(pQAttr->iFS);
00659    else
00660       iStage = 0;
00661    pComm->iStageFSid = htonl(iStage);
00662 
00663    if (iDebug)
00664    {
00665       printf("    file %s found (obj-id %d-%d)",
00666              pComm->cNamell,
00667              ntohl(pQAttr->iObjHigh),
00668              ntohl(pQAttr->iObjLow));
00669       if (iStage)
00670          printf( ", on %s in StageFS %d\n", pQAttr->cNode, iStage);
00671       else
00672          printf( "\n");
00673    }
00674 
00675    pComm->iAction = htonl(REMOVE);
00676    pComm->iObjHigh = pQAttr->iObjHigh;
00677    pComm->iObjLow = pQAttr->iObjLow;
00678 
00679    pc = (char *) pComm;
00680    if ( (iRC = send( iSocket, pc, iBufComm, 0 )) < 0 )
00681    {
00682       perror("-E- sending command buffer");
00683       printf("-E- %s: sending delete request %s\n",
00684              cModule, pComm->cNamell);
00685       return -1;
00686    }
00687 
00688    if (iDebug) printf(
00689       "-D- delete command sent to server (%d bytes), look for reply\n",
00690       iBufComm);
00691 
00692    /*********** look for reply from server *****************/
00693 
00694    pc = (char *) &sStatus;
00695    iRC = rawRecvStatus(iSocket, &pc);
00696    if (iRC < HEAD_LEN)
00697    {
00698       printf("-E- receiving status buffer with delete information\n");
00699       return(-1);
00700    }
00701    if (iRC > HEAD_LEN)
00702    {
00703       printf("-E- message received from server:\n");
00704       printf("%s", sStatus.cStatus);
00705       return(-1);
00706    }
00707 
00708    if (iDebug)
00709       printf("    status (%d) received from server (%d bytes)\n",
00710              sStatus.iStatus, iRC);
00711 
00712    printf("-I- Object %s%s%s successfully deleted",
00713           pComm->cNamefs, pComm->cNamehl, pComm->cNamell);
00714    if (iStage)
00715       printf( " (staged)\n");
00716    else
00717       printf( "\n");
00718 
00719    if (iDebug)
00720       printf("-D- end %s\n\n", cModule);
00721 
00722    return 0;
00723 
00724 } /* end rawDelFile */
00725 
00726 /*********************************************************************
00727  * rawDelList:  delete list of files in GSI mass storage
00728  *
00729  * created 22.10.1997, Horst Goeringer
00730  *********************************************************************
00731  */
00732 
00733 int rawDelList( int iDataMover,
00734                 srawDataMoverAttr *pDataMover0,
00735                 srawComm *psComm,
00736                 char **pcFileList,
00737                 char **pcObjList)
00738 {
00739    char cModule[32] = "rawDelList";
00740    int iDebug = 0;
00741 
00742    int iSocket;
00743    char *pcfl, *pcol;
00744    int *pifl, *piol;
00745    int ifile;
00746    int iobj0, iobj, iobjf = 0;
00747    int iobjBuf;
00748 
00749    srawArchList *psFile, *psFile0;           /* files to be archived */
00750    srawRetrList *psObj;                  /* objects already archived */
00751    srawDataMoverAttr *pDataMover;              /* current data mover */
00752 
00753    char cFilell[MAX_OBJ_LL];
00754    char *pc, *pdelim;
00755 
00756    bool_t bDelete, bDelDone;
00757    int **piptr;                  /* points to pointer to next buffer */
00758 
00759    int ii, jj, kk;
00760    int iRC, idel;
00761 
00762    pcfl = *pcFileList;
00763    pifl = (int *) pcfl;
00764    ifile = pifl[0];                            /* number of files */
00765    psFile = (srawArchList *) ++pifl;  /* points now to first file */
00766    psFile0 = psFile;
00767    pifl--;                     /* points again to number of files */
00768 
00769    if (iDebug)
00770    {
00771       printf("\n-D- begin %s\n", cModule);
00772       printf("    initial %d files, first file %s\n",
00773              ifile, psFile0->cFile);
00774    }
00775 
00776    pDataMover = pDataMover0;
00777    if (iDataMover == 1)
00778    {
00779       iSocket = pDataMover->iSocket;
00780       if (iDebug) printf(
00781          "    one data mover %s, socket %d\n",
00782          pDataMover->cNode, iSocket);
00783    }
00784 
00785    pcol = *pcObjList;
00786    piol = (int *) pcol;
00787    iobj0 = 0;                     /* total no. of archived objects */
00788 
00789    iobjBuf = 0;                             /* count query buffers */
00790    idel = 0;                                /* count deleted files */
00791    bDelDone = bFalse;
00792    while (!bDelDone)
00793    {
00794       iobjBuf++;
00795       iobj = piol[0];            /* no. of objects in query buffer */
00796       psObj = (srawRetrList *) ++piol;
00797                                      /* points now to first object */
00798       if (iDebug)
00799          printf("    buffer %d: %d objects, first obj %s (server %d)\n",
00800                 iobjBuf, iobj, psObj->cNamell, psObj->iMaster);
00801 
00802       psComm->iAction = htonl(REMOVE);
00803       for (ii=1; ii<=iobj; ii++)    /* loop over objects in buffer */
00804       {
00805          iobj0++;
00806          pc = (char *) psObj;
00807          pc++;                           /* skip object delimiter  */
00808 
00809          bDelete = bFalse;
00810          psFile = psFile0;
00811          for (jj=1; jj<=ifile; jj++)                  /* file loop */
00812          {
00813             pdelim = strrchr(psFile->cFile, *pcFileDelim);
00814             if (pdelim == NULL)
00815             {
00816 #ifdef VMS
00817                pdelim = strrchr(psFile->cFile, *pcFileDelim2);
00818                if (pdelim != NULL) pdelim++;
00819                else
00820 #endif
00821                pdelim = psFile->cFile;
00822             }
00823             else pdelim++;                 /* skip file delimiter  */
00824 
00825             iRC = strcmp(pdelim, pc);
00826             if ( iRC == 0 )
00827             {
00828                bDelete = bTrue;
00829                break;
00830             }
00831             psFile++;
00832          } /* file loop (jj) */
00833 
00834          if (bDelete)
00835          {
00836             if (iDebug)
00837             {
00838                printf("    found file %d: %s, obj %d: %s",
00839                       jj, psFile->cFile, ii, psObj->cNamell);
00840                if (psObj->iStageFS)
00841                   printf(", on DM %s in StageFS %s\n",
00842                          psObj->cNodeMover, psObj->iStageFS);
00843                else if (psObj->iArchiveFS)
00844                {
00845                   printf(", on DM %s in ArchiveFS %s\n",
00846                          psObj->cNodeMover, psObj->iArchiveFS);
00847                   printf("    archived at %s by %s\n",
00848                          psObj->cArchiveDate, psObj->cOwner);
00849                }
00850                else
00851                   printf(" (not in disk pool)\n");
00852             }
00853 
00854             iRC = rawGetLLName(psFile->cFile,
00855                                 pcObjDelim, psComm->cNamell);
00856 
00857             if (iDataMover > 1)
00858             {
00859                if ((strcmp(pDataMover->cNode,psObj->cNodeMover) == 0) ||
00860                    (strlen(psObj->cNodeMover) == 0))   /* not staged */
00861                {
00862                   iSocket = pDataMover->iSocket;
00863                   if (iDebug) printf(
00864                      "    current data mover %s, socket %d\n",
00865                      pDataMover->cNode, iSocket);
00866                }
00867                else
00868                {
00869                   pDataMover = pDataMover0;
00870                   for (kk=1; kk<=iDataMover; kk++)
00871                   {
00872                      if (strcmp(pDataMover->cNode,
00873                                 psObj->cNodeMover) == 0)
00874                         break;
00875                      pDataMover++;
00876                   }
00877 
00878                   if (kk > iDataMover)
00879                   {
00880                      printf("-E- %s: data mover %s not found in list\n",
00881                             cModule, psObj->cNodeMover);
00882                      return -1;
00883                   }
00884 
00885                   iSocket = pDataMover->iSocket;
00886                   if (iDebug) printf(
00887                      "    new data mover %s, socket %d\n",
00888                      pDataMover->cNode, iSocket);
00889                }
00890             } /* (iDataMover > 1) */
00891 
00892             iRC = rawDelFile(iSocket, psComm);
00893             if (iRC)
00894             {
00895                if (iDebug)
00896                   printf("    rawDelFile: rc = %d\n", iRC);
00897                if (iRC < 0)
00898                {
00899                   printf("-E- %s: file %s could not be deleted\n",
00900                          cModule, psFile->cFile);
00901                   return -1;
00902                }
00903                /* else: object not found, ignore */
00904 
00905             } /* (iRC) */
00906             idel++;
00907 
00908          } /* if (bDelete) */
00909          psObj++;
00910 
00911       } /* loop over objects in query buffer (ii) */
00912 
00913       piptr = (int **) psObj;
00914       if (*piptr == NULL) bDelDone = bTrue;
00915       else piol = *piptr;
00916 
00917    } /* while (!bDelDone) */
00918 
00919    if (iDebug) printf("-D- end %s\n\n", cModule);
00920 
00921    return(idel);
00922 
00923 } /* rawDelList */
00924 
00925 /**********************************************************************
00926  * rawGetFilelistEntries:
00927  *    get filelist entries from input file
00928  *    uses external buffer ptr piEntryList provided by caller
00929  *    removes tape file specifications
00930  *    replaces '%' (historical) by '?' (supported by TSM)
00931  *    removes tape file specifications
00932  *    removes duplicate entries
00933  *    orders: generic file names first
00934  *
00935  * created 22. 5.2003 by Horst Goeringer
00936  **********************************************************************
00937  */
00938 
00939 int rawGetFilelistEntries( char *pcFileName,
00940                            int *piEntries)
00941 {
00942    char cModule[32] = "rawGetFilelistEntries";
00943    int iDebug = 0;
00944 
00945    int ii, jj;
00946    int imax = MAX_FILE;
00947    char cEntry[MAX_FILE] = "", *pcEntry;
00948    char cFileName[MAX_FILE] = "";
00949    char cQualifier[16] = ".filelist";
00950    char *pcLeading = "@";
00951    char *pcc;
00952    char *ploc;
00953 
00954    int iRemove;
00955    int iGeneric = 0;                 /* = 1: generic file name found */
00956    int iSingle = 0;   /* = 1: file name without wildcard chars found */
00957    int iRC;
00958    int iError;
00959 
00960    int iGenericEntries = 0;
00961    int iSingleEntries = 0;
00962    int iEntries = -1;
00963    FILE *fiFile = NULL;
00964 
00965    int iMaxEntries;
00966    int iSizeBuffer;
00967    int *piFilelist, *piFilelisto;
00968    srawArchList *pFilelist,                  /* first filelist entry */
00969                 *pFilelistc,               /* current filelist entry */
00970                 *pFilelistco,   /* current filelist entry old buffer */
00971                 *pFilelistc0;   /* current filelist entry for remove */
00972 
00973    if (iDebug)
00974       printf("\n-D- begin %s\n", cModule);
00975 
00976    piFilelist = piEntryList;             /* copy of external pointer */
00977 
00978    if (strlen(pcFileName) >= imax)
00979    {
00980       fprintf(fLogFile,
00981          "-E- %s: file name too long (max %d)\n",
00982          cModule, --imax);
00983       iError = -1;
00984       goto gErrorFilelist;
00985    }
00986    strcpy(cFileName, pcFileName);                      /* local copy */
00987 
00988    iRC = strncmp(cFileName, pcLeading, 1);
00989    if (iRC)
00990    {
00991       if (iDebug) fprintf(fLogFile,
00992          "    no leading %s\n", pcLeading);
00993       goto gEndFilelist;
00994    }
00995 
00996    pcc = cQualifier;
00997    ploc = strrchr(cFileName, pcc[0]);
00998    if (ploc != NULL)
00999    {
01000       ploc++;
01001       pcc++;
01002       if (strcmp(ploc, pcc) != 0)
01003       {
01004          if (iDebug) fprintf(fLogFile,
01005             "    no trailing %s\n", cQualifier);
01006          goto gEndFilelist;
01007       }
01008    }
01009    else
01010    {
01011       if (iDebug) fprintf(fLogFile,
01012          "    no trailing %s\n", cQualifier);
01013       goto gEndFilelist;
01014    }
01015 
01016    if (iDebug) fprintf(fLogFile,
01017       "    %s is a filelist\n", cFileName);
01018 
01019    fiFile = fopen(pcFileName, "r");
01020    if (fiFile == NULL)
01021    {
01022       fprintf(fLogFile, "-E- %s: opening filelist %s\n",
01023               cModule, pcFileName);
01024       perror("    ");
01025       iError = -1;
01026       goto gErrorFilelist;
01027    }
01028    if (iDebug) fprintf(fLogFile,
01029       "    filelist %s opened\n", pcFileName);
01030 
01031    piFilelisto = piFilelist;
01032    iMaxEntries = *piFilelist;
01033    if (iDebug) fprintf(fLogFile,
01034       "    max no. of entries in filelist buffer: %d\n", iMaxEntries);
01035    if (iDebug == 2) fprintf(fLogFile,
01036       "DDD piFilelist %d, *piFilelist %d\n",
01037       piFilelist, *piFilelist);
01038 
01039    pFilelist = (srawArchList *) &(piFilelist[1]);
01040                                           /* skip max no. of entries */
01041    pFilelistc = pFilelist;                          /* current entry */
01042    pcEntry = cEntry;
01043    iEntries = 0;
01044    for(;;)
01045    {
01046       pcEntry = fgets(cEntry, imax, fiFile);
01047 
01048       if ( (pcEntry != NULL) && (strlen(pcEntry) > 1) )
01049       {
01050          ploc = strchr(pcEntry, '\n');
01051          if (ploc != NULL)
01052             *ploc = '\0';
01053 
01054          ploc = strchr(pcEntry, *pcDevDelim);
01055          if (ploc != NULL)
01056          {
01057             fprintf(fLogFile,
01058                "-W- no local tape support in filelist, %s ignored\n",
01059                pcEntry);
01060             continue;
01061          }
01062 
01063          /* replace '%' (historical) by '?' (supported by TSM) */
01064          while ( (ploc = strchr(pcEntry, *pcPerc)) != NULL)
01065          {
01066             if (iDebug)
01067                fprintf(fLogFile, "-W- replace %s", pcEntry);
01068             *ploc = *pcQM;
01069             if (iDebug)
01070                fprintf(fLogFile, " by %s\n", pcEntry);
01071          }
01072 
01073          if (iEntries == iMaxEntries)    /* reallocate for new entry */
01074          {
01075             iMaxEntries += iMaxEntries;
01076             if (iDebug) fprintf(fLogFile,
01077                "    entry buffer full, reallocate: max %d entries\n",
01078                iMaxEntries);
01079 
01080             iSizeBuffer = iMaxEntries*MAX_FILE + sizeof(int);
01081             piFilelisto = piFilelist;
01082             piFilelist = (int *) calloc(iSizeBuffer, sizeof(char) );
01083             if (piFilelist == NULL)
01084             {
01085                fprintf(fLogFile,
01086                   "-E- reallocating filelist buffer (size %d)\n",
01087                   iSizeBuffer);
01088                perror("-E- reallocating filelist buffer");
01089                iError = -1;
01090                goto gErrorFilelist;
01091             }
01092 
01093             if (iDebug) fprintf(fLogFile,
01094                "    filelist entry buffer reallocated (size %d)\n",
01095                iSizeBuffer);
01096 
01097             *piFilelist = iMaxEntries;
01098             if (iDebug == 2) fprintf(fLogFile,
01099                "DDD piFilelist %d, *piFilelist %d\n",
01100                 piFilelist, *piFilelist);
01101 
01102             pFilelistc = (srawArchList *) &(piFilelist[1]);   /* new */
01103             pFilelistco = pFilelist;                   /* old buffer */
01104             pFilelist = pFilelistc;              /* first new buffer */
01105 
01106             for (ii=1; ii<=iEntries; ii++)
01107             {
01108                if (iDebug == 2) fprintf(fLogFile,
01109                   "DDD pFilelistc %d\n", pFilelistc);
01110                strcpy(pFilelistc->cFile, pFilelistco->cFile);
01111                pFilelistc++;
01112                pFilelistco++;
01113             }
01114 
01115             if (iDebug) fprintf(fLogFile,
01116                "    %d old entries copied to new buffer, next:\n",
01117                iEntries);
01118 
01119             if (iDebug == 2) fprintf(fLogFile,
01120                "DDD free piFilelisto %d\n", piFilelisto);
01121             free(piFilelisto);
01122             piFilelisto = piFilelist;
01123          } /* (iEntries == iMaxEntries) */
01124 
01125          if (iDebug == 2) fprintf(fLogFile,
01126             "DDD pFilelistc %d\n", pFilelistc);
01127          strcpy(pFilelistc->cFile, pcEntry);
01128          iEntries++;
01129 
01130          if (iDebug) fprintf(fLogFile,
01131             "    %3d: %s \n", iEntries, pFilelistc->cFile);
01132 
01133          pFilelistc++;
01134       }
01135       else
01136          break;
01137 
01138    } /* read loop */
01139 
01140    pFilelistc = pFilelist;
01141    if (iDebug)
01142       for (ii=1; ii<=iEntries; ii++)
01143    {
01144       fprintf(fLogFile,
01145          "    %3da: %s \n", ii, pFilelistc->cFile);
01146       pFilelistc++;
01147    }
01148 
01149    /* check if duplicate entries */
01150    if (iEntries)
01151    {
01152       pFilelistc = pFilelist;
01153       iRemove = 0;
01154       for (ii=1; ii<iEntries; ii++)
01155       {
01156          if (strlen(pFilelistc->cFile) == 0)      /* already removed */
01157          {
01158             pFilelistc++;
01159             continue;
01160          }
01161 
01162          pFilelistco = pFilelistc;
01163          pFilelistco++;
01164          for (jj=ii+1; jj<=iEntries; jj++)
01165          {
01166             if (strcmp(pFilelistc->cFile, pFilelistco->cFile) == 0)
01167             {
01168                if (iDebug)
01169                   fprintf(fLogFile, "-W- duplicate entry %s removed\n",
01170                           pFilelistco->cFile);
01171                strcpy(pFilelistco->cFile, "");
01172                iRemove++;
01173             }
01174             pFilelistco++;
01175          }
01176 
01177          pFilelistc++;
01178       }
01179 
01180       if (iDebug)
01181       {
01182          if (iRemove) fprintf(fLogFile,
01183             "    %d duplicate entries found in list\n", iRemove);
01184          else fprintf(fLogFile,
01185             "    no duplicate entries found in list\n");
01186       }
01187    } /* (iEntries) */
01188    else if (iDebug)
01189       fprintf(fLogFile, "    no entries found in list\n");
01190 
01191    pFilelistc = pFilelist;
01192    if (iDebug)
01193       for (ii=1; ii<=iEntries; ii++)
01194    {
01195       fprintf(fLogFile,
01196          "    %3db: %s \n", ii, pFilelistc->cFile);
01197       pFilelistc++;
01198    }
01199 
01200    /* reorder remaining entries */
01201    if (iRemove)
01202    {
01203       pFilelistc = pFilelist;
01204       for (ii=1; ii<iEntries; ii++)
01205       {
01206          if (strlen(pFilelistc->cFile) == 0)              /* removed */
01207          {
01208             pFilelistco = pFilelistc;
01209             pFilelistco++;
01210             pFilelistc0 = pFilelistc;
01211             for (jj=ii+1; jj<=iEntries; jj++)
01212             {
01213                strcpy(pFilelistc0->cFile, pFilelistco->cFile);
01214                pFilelistc0++;
01215                pFilelistco++;
01216             }
01217             continue;
01218                 /* no ptr incr, as same location to be checked again */
01219          }
01220          pFilelistc++;
01221       }
01222       iEntries -= iRemove;
01223    }
01224 
01225    /* check if sorting necessary */
01226    pFilelistc = pFilelist;
01227    for (ii=1; ii<=iEntries; ii++)
01228    {
01229       ploc = strchr(pFilelistc->cFile, *pcStar);
01230       if (ploc != NULL)
01231          iGeneric = 1;
01232       else
01233       {
01234          ploc = strchr(pFilelistc->cFile, *pcQM);
01235          if (ploc != NULL)
01236             iGeneric = 1;
01237          else
01238          {
01239             ploc = strchr(pFilelistc->cFile, *pcPerc);
01240             if (ploc != NULL)
01241                iGeneric = 1;
01242             else
01243                iSingle = 1;
01244          }
01245       }
01246       if ( (iGeneric) && (iSingle) )
01247          break;
01248 
01249       pFilelistc++;
01250    }
01251 
01252    pFilelistc = pFilelist;
01253    if (iDebug)
01254       for (ii=1; ii<=iEntries; ii++)
01255    {
01256       fprintf(fLogFile,
01257          "    %3dc: %s \n", ii, pFilelistc->cFile);
01258       pFilelistc++;
01259    }
01260 
01261    /* reorder: generic names first */
01262    if ( (iGeneric) && (iSingle) )
01263    {
01264       piFilelisto = piFilelist;
01265 
01266       /* create buffer for sorted entries */
01267       iSizeBuffer = iEntries*MAX_FILE + sizeof(int);
01268       piFilelist = (int *) calloc(iSizeBuffer, sizeof(char) );
01269       if (piFilelist == NULL)
01270       {
01271          fprintf(fLogFile,
01272             "-E- allocating ordered filelist buffer (size %d)\n",
01273             iSizeBuffer);
01274          perror("-E- allocating ordered filelist buffer");
01275          iError = -1;
01276          goto gErrorFilelist;
01277       }
01278 
01279       if (iDebug) fprintf(fLogFile,
01280          "    ordered filelist buffer allocated (size %d)\n",
01281          iSizeBuffer);
01282 
01283       *piFilelist = iEntries;
01284       if (iDebug == 2) fprintf(fLogFile,
01285          "DDD piFilelist %d, *piFilelist %d\n",
01286          piFilelist, *piFilelist);
01287 
01288       pFilelistc = (srawArchList *) &(piFilelist[1]);
01289       pFilelist = pFilelistc;
01290       pFilelistco = (srawArchList *) &(piFilelisto[1]);
01291       iGenericEntries = 0;
01292 
01293       /* copy generic entries */
01294       for (ii=1; ii<=iEntries; ii++)
01295       {
01296          iGeneric = 0;
01297          iSingle = 0;
01298          ploc = strchr(pFilelistco->cFile, *pcStar);
01299          if (ploc != NULL)
01300             iGeneric = 1;
01301          else
01302          {
01303             ploc = strchr(pFilelistco->cFile, *pcQM);
01304             if (ploc != NULL)
01305                iGeneric = 1;
01306             else
01307             {
01308                ploc = strchr(pFilelistco->cFile, *pcPerc);
01309                if (ploc != NULL)
01310                   iGeneric = 1;
01311                else
01312                   iSingle = 1;
01313             }
01314          }
01315 
01316          if (iGeneric)
01317          {
01318             strcpy(pFilelistc->cFile, pFilelistco->cFile);
01319             strcpy(pFilelistco->cFile, "");
01320             pFilelistc++;
01321             iGenericEntries++;
01322          }
01323          pFilelistco++;
01324 
01325       } /* loop pFilelistco */
01326 
01327       pFilelistco = (srawArchList *) &(piFilelisto[1]);
01328       iSingleEntries = 0;
01329 
01330       /* copy non-generic entries */
01331       for (ii=1; ii<=iEntries; ii++)
01332       {
01333          if (strlen(pFilelistco->cFile) != 0)
01334          {
01335             strcpy(pFilelistc->cFile, pFilelistco->cFile);
01336             pFilelistc++;
01337             iSingleEntries++;
01338          }
01339          pFilelistco++;
01340       }
01341 
01342       if (iDebug) fprintf(fLogFile,
01343          "    %d generic file names, followed by %d non-generic file names\n",
01344          iGenericEntries, iSingleEntries);
01345 
01346    } /* (iGeneric) && (iSingle) */
01347 
01348    pFilelistc = pFilelist;
01349    if (iDebug)
01350       for (ii=1; ii<=iEntries; ii++)
01351    {
01352       fprintf(fLogFile,
01353          "    %3dd: %s \n", ii, pFilelistc->cFile);
01354       pFilelistc++;
01355    }
01356 
01357 gEndFilelist:
01358    *piEntries = iEntries;
01359    iError = 0;
01360 
01361    if (iDebug == 2) fprintf(fLogFile,
01362       "DDD piFilelist %d, *piFilelist %d\n", piFilelist, *piFilelist);
01363 
01364 gErrorFilelist:
01365    if (fiFile)
01366    {
01367       iRC = fclose(fiFile);
01368       if (iRC)
01369       {
01370          fprintf(fLogFile, "-E- %s: closing filelist %s\n",
01371                  cModule, pcFileName);
01372          perror("    ");
01373       }
01374    }
01375 
01376    piEntryList = piFilelist;             /* pass to external pointer */
01377 
01378    if (iDebug)
01379       printf("-D- end %s\n\n", cModule);
01380 
01381    return iError;
01382 
01383 } /* rawGetFilelistEntries */
01384 
01385 /********************************************************************
01386  * rawGetWSInfo: get workspace and pool info from master server
01387  *
01388  * created 30. 6.2003 by Horst Goeringer
01389  ********************************************************************
01390  */
01391 
01392 int rawGetWSInfo( srawCliActionComm *pCliActionComm,
01393                   srawPoolStatus *pPoolInfo,
01394                   srawWorkSpace **ppWorkSpace)
01395 {
01396    int iDebug = 0;
01397    char cModule[32] = "rawGetWSInfo";
01398    int iRC;
01399    int iSocket;
01400    int iPoolInfo;               /* =1: provide info on stage pool(s) */
01401    int iPrintPoolInfo;            /* =1: print info on stage pool(s) */
01402    int iWorkSpaceInfo;              /* =1: provide info on workspace */
01403 
01404    int iAction;
01405 
01406    int iBuf;
01407    int ii;
01408    int iIdent;
01409    int iStatus;
01410    int iAttrLen;
01411 
01412    int iPoolId;            /* identifier of requested pool, = 0: all */
01413    int iPoolMode = 0;        /* =1: retrieve, =2: stage, =3: archive */
01414    int iSleepClean = 0;          /* sleep if clean job needs started */
01415 
01416    int iPoolmax;
01417    int iPoolcur;
01418    int iBufPool;
01419 
01420    char cPoolNameRand[32] = "RetrievePool";
01421    char cPoolNameTemp[32] = "StagePool";
01422    int iHardwareFree = 0;          /* free space in hardware (MByte) */
01423    int iPoolRandFree;           /* free space of random pool (MByte) */
01424    int iPoolRandUsed;           /* used space of random pool (MByte) */
01425    int iRandomExcess = 0;
01426           /* unused space of other pools used in random pool (MByte) */
01427    int iPoolTempAvail = 0;
01428    int iPoolTempMax;            /* overall size of temp pool (MByte) */
01429    int iPoolTempMaxWS;           /* max WS size in temp pool (MByte) */
01430    int iPoolTempFree;             /* free space of temp pool (MByte) */
01431    int iPoolTempUsed;             /* used space of temp pool (MByte) */
01432    int iPoolTempCheck;
01433                   /* min work space check size for temp pool (MByte) */
01434    int iTempSizeUnavail = 0;
01435                /* temp pool space currently allocated by other pools */
01436 
01437    int iWorkSizeNew;
01438               /* still to be staged for requested work space (MByte) */
01439    int iWorkSizeAll;         /* size of requested work space (MByte) */
01440    int iWorkFilesAll;            /* total no. of files in work space */
01441    int iWorkSizeSta = 0;  /* part of requ. work space already staged */
01442    int iWorkFilesSta = 0;
01443                         /* no. of files in work space already staged */
01444    int iWorkSizeStaTemp = 0;
01445                            /* part of staged work space in temp pool */
01446    int iWorkFilesStaTemp = 0;    /* no. of staged files in temp pool */
01447    int iWorkSizeStaRand = 0;
01448                          /* part of staged work space in random pool */
01449    int iWorkFilesStaRand = 0;  /* no. of staged files in random pool */
01450    int iWorkSizeEst = 0;  /* part of requ. work space size estimated */
01451    int iWorkFilesEst = 0;
01452                    /* no. of files in work space with size estimated */
01453    int iWorkSizeIncompl = 0;
01454                      /* part of work space not yet completely staged */
01455    int iWorkFilesIncompl = 0;
01456              /* no. of files in work space not yet completely staged */
01457    int iWorkStatus = 0;       /* status of work space sent by server */
01458 
01459 
01460    int *piBuffer;
01461    char *pcc;
01462    char cMsg[256] = "";
01463    char cMsgPref[8] = "";
01464    char cMisc[128] = "";
01465    char pcGenFile[MAX_FILE] = "";        /* full (generic) file name */
01466 
01467    srawWorkSpace *pWorkSpace;
01468    srawPoolStatusData *pPoolInfoData, *pPoolInfoData0;
01469 
01470    if (iDebug)
01471       printf("\n-D- begin %s\n", cModule);
01472 
01473    piBuffer = pCliActionComm->piBuffer;      /* area to receive data */
01474    iSocket = pCliActionComm->iSocket;
01475    iAction = pCliActionComm->iAction;
01476 
01477    iPoolInfo = 1;
01478    if (iAction == QUERY_POOL)
01479    {
01480       iPoolId = pCliActionComm->iStatus;
01481       iPrintPoolInfo = 1;
01482       iWorkSpaceInfo = 0;
01483    }
01484    else
01485    {
01486       strcpy(pcGenFile, pCliActionComm->pcFile);
01487       iPoolId = 2;
01488       if (pCliActionComm->iStatus)
01489          iPrintPoolInfo = 1;
01490       else
01491          iPrintPoolInfo = 0;
01492       iWorkSpaceInfo = 1;
01493    }
01494 
01495    if (iDebug)
01496    {
01497       printf("    action %d", iAction);
01498       if (iPrintPoolInfo)
01499          printf(", print pool info");
01500       if (iAction == QUERY_POOL)
01501          printf(", poolId  %d\n", iPoolId);
01502       else
01503          printf("\n");
01504    }
01505 
01506    if (iPoolInfo)
01507    {
01508       pcc = (char *) piBuffer;               /* header for pool info */
01509       pPoolInfo = (srawPoolStatus *) piBuffer;         /* for caller */
01510       iRC = rawRecvHead(iSocket, &pcc);
01511       if (iRC <= 0)
01512       {
01513         printf("-E- receiving header pool status from master server\n");
01514         return -1;
01515       }
01516 
01517       if (iDebug)
01518          printf("    header pool status received (%d bytes)\n", iRC);
01519 
01520       iIdent = ntohl(pPoolInfo->iIdent);
01521       iStatus = ntohl(pPoolInfo->iPoolNo);
01522       iAttrLen = ntohl(pPoolInfo->iStatusLen);
01523 
01524       /* expect IDENT_POOL */
01525       if (iIdent != IDENT_POOL)
01526       {
01527          if (iIdent == IDENT_STATUS)
01528          {
01529             if ( (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) )
01530             {
01531                printf("-E- received error status from server");
01532                if (iDebug)
01533                   printf(" instead of pool info:\n");
01534                else printf(":\n");
01535 
01536                if (iAttrLen > 0)
01537                {
01538                   pcc = cMsg;
01539                   iRC = rawRecvError(iSocket, iAttrLen, &pcc);
01540                   if (iRC < 0) printf(
01541                      "-E- receiving error msg from server, rc = %d\n",
01542                      iRC);
01543                   else printf("    %s\n", pcc);
01544                }
01545                else printf("    no error message available\n");
01546 
01547             } /* (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) */
01548             else
01549             {
01550                printf(
01551                   "-E- unexpected status (type %d) received from server\n",
01552                   iStatus);
01553             }
01554          } /* iIdent == IDENT_STATUS */
01555          else
01556          {
01557             printf(
01558                "-E- unexpected header (%d) received from server\n",
01559                iIdent);
01560          }
01561 
01562          return -1;
01563 
01564       } /* (iIdent != IDENT_POOL) ) */
01565 
01566       iPoolmax = iStatus;
01567       iBufPool = iAttrLen;        /* size pool buffer without header */
01568 
01569       pcc += HEAD_LEN;
01570       pPoolInfoData = (srawPoolStatusData *) pcc;
01571       pPoolInfoData0 = pPoolInfoData;             /* first pool info */
01572 
01573       /* receive staging pool info */
01574       iBuf = iBufPool;
01575       while(iBuf > 0)
01576       {
01577          if ( (iRC = recv( iSocket, pcc, iBuf, 0 )) < 0 )
01578          {
01579             perror("-E- receiving pool info");
01580             return -1;
01581          }
01582          iBuf -= iRC;
01583          pcc += iRC;
01584       } /* while(iBuf > 0) */
01585 
01586       if (iDebug) printf(
01587          "    stage pool status received (%d bytes)\n", iBufPool);
01588 
01589       /* get pool names first for info messages */
01590       if ( (iAction == QUERY_POOL) || (iAction == QUERY_WORKSPACE) ||
01591            (iAction == STAGE) )
01592          for (iPoolcur=1; iPoolcur<=iPoolmax; iPoolcur++)
01593       {
01594          if (iPoolcur == 1)
01595          {
01596             iHardwareFree = ntohl(pPoolInfoData->iFreeSizeHW);
01597             iPoolRandFree = ntohl(pPoolInfoData->iFreeSize);
01598          }
01599          if (iPoolcur == 2)
01600             iPoolTempFree = ntohl(pPoolInfoData->iFreeSize);
01601 
01602          if (strcmp(pPoolInfoData->cPoolName, "RetrievePool") == 0)
01603             iPoolMode = 1;
01604          if (strcmp(pPoolInfoData->cPoolName, "StagePool") == 0)
01605             iPoolMode = 2;
01606 
01607          if ( (iAction == QUERY_POOL) || (iAction == QUERY_WORKSPACE) )
01608          {
01609             if (iPoolMode == 1)
01610             {
01611                if (iPrintPoolInfo) printf(
01612                   "-I- overall space %s %7d MByte, free %7d MByte\n",
01613                   pPoolInfoData->cPoolOS,
01614                   ntohl(pPoolInfoData->iMaxSizeHW), iHardwareFree);
01615 
01616                if ( (iPoolId == iPoolMode) || (iPoolId == 0) )
01617                {
01618                   printf("    %s: used for 'tsmcli retrieve'\n",
01619                      pPoolInfoData->cPoolName);
01620 
01621                   iPoolRandUsed = ntohl(pPoolInfoData->iMaxSize) -
01622                                   iHardwareFree;
01623                   if (iPoolRandFree < 0)
01624                      iRandomExcess = -iPoolRandFree;
01625 
01626                   printf(
01627                      "          used space  %7d MByte, free %7d MByte, %d files stored\n",
01628                      iPoolRandUsed, iHardwareFree,
01629                      ntohl(pPoolInfoData->iFiles));
01630 
01631                   if (iAction == QUERY_POOL)
01632                   {
01633                      if (iRandomExcess > 0)
01634                         printf("       %7d MByte lent from StagePool\n",
01635                                iRandomExcess);
01636                      else if (iHardwareFree > 0)
01637                         printf("       unused space also usable for StagePool\n");
01638                   }
01639 
01640                } /* (iPoolId == iPoolMode) || (iPoolId == 0) */
01641             } /* (iPoolMode == 1) */
01642 
01643             if (iPoolMode == 2)
01644             {
01645                if ( (iPoolId == iPoolMode) || (iPoolId == 0) )
01646                {
01647                   if (iPrintPoolInfo) printf(
01648                      "    %s: used for 'tsmcli stage'\n",
01649                      pPoolInfoData->cPoolName);
01650                   iPoolTempAvail = ntohl(pPoolInfoData->iFileAvail);
01651 
01652                   iPoolTempUsed = ntohl(pPoolInfoData->iMaxSize) -
01653                                   iPoolTempFree;
01654                   if (iPoolTempFree < 0)
01655                      iPoolTempFree = 0;
01656 
01657                   if (iHardwareFree < iPoolTempFree)
01658                      iTempSizeUnavail = iPoolTempFree - iHardwareFree;
01659 
01660                   if ( (iPoolTempFree >= 0) && (iPrintPoolInfo) )
01661                   {
01662                      printf( "          used space  %7d MByte, free %7d MByte, %d files stored\n",
01663                         iPoolTempUsed, iPoolTempFree,
01664                         ntohl(pPoolInfoData->iFiles));
01665                      if (iTempSizeUnavail)
01666                      {
01667                         printf( "       thereof currently %7d MByte free, remainder can be freed\n",
01668                            iHardwareFree);
01669                      }
01670                      else
01671                         if ( (iAction == QUERY_POOL) &&
01672                              (iPoolTempFree > 0) )
01673                            printf("       unused space also usable for RetrievePool\n");
01674                   }
01675                   if (iPrintPoolInfo) printf(
01676                      "       min availability of %d days guaranteed\n",
01677                      ntohl(pPoolInfoData->iFileAvail));
01678 
01679                } /* (iPoolId == iPoolMode) || (iPoolId == 0) */
01680             } /* (iPoolMode == 2) */
01681          } /* (iAction == QUERY_POOL) || (iAction == QUERY_WORKSPACE) */
01682 
01683          if ( (iPoolMode == 2) &&
01684               ((iAction == STAGE) || (iAction == QUERY_WORKSPACE)) )
01685          {
01686             iPoolTempMax = ntohl(pPoolInfoData->iMaxSize);
01687             iPoolTempMaxWS = ntohl(pPoolInfoData->iMaxWorkSize);
01688             iPoolTempCheck = ntohl(pPoolInfoData->iCheckSize);
01689          }
01690 
01691          pPoolInfoData++;
01692 
01693       } /* loop pools */
01694       pPoolInfoData = pPoolInfoData0;              /* 1st pool again */
01695 
01696    } /* (iPoolInfo) */
01697 
01698    /********************* get work space info ************************/
01699 
01700    if (iWorkSpaceInfo)
01701    {
01702       pWorkSpace = (srawWorkSpace *) pcc;
01703       *ppWorkSpace = pWorkSpace;                       /* for caller */
01704 
01705       iRC = rawRecvHead(iSocket, &pcc);
01706       if (iRC <= 0)
01707       {
01708          printf("-E- receiving work space buffer header\n");
01709          return -1;
01710       }
01711       if (iDebug)
01712          printf("-D- header work space buffer received (%d bytes)\n",
01713                 iRC);
01714 
01715       iIdent = ntohl(pWorkSpace->iIdent);
01716       iStatus = ntohl(pWorkSpace->iWorkId);
01717       iAttrLen = ntohl(pWorkSpace->iStatusLen);
01718 
01719       /* expect IDENT_WORKSPACE */
01720       if (iIdent != IDENT_WORKSPACE)
01721       {
01722          if (iIdent == IDENT_STATUS)
01723          {
01724             if ( (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) )
01725             {
01726                if (iDebug) printf("\n");
01727                printf("-E- received error status from server");
01728                if (iDebug)
01729                   printf(" instead of work space info:\n");
01730                else printf(":\n");
01731 
01732                if (iAttrLen > 0)
01733                {
01734                   pcc = (char *) piBuffer;
01735                   iRC = rawRecvError(iSocket, iAttrLen, &pcc);
01736                   if (iRC < 0) printf(
01737                      "-E- receiving error msg from server, rc = %d\n",
01738                      iRC);
01739                   else printf("    %s\n", pcc);
01740                }
01741                else printf("    no error message available\n");
01742 
01743             } /* (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) */
01744             else
01745             {
01746                printf(
01747                   "-E- unexpected status (%d) received from server\n",
01748                   iStatus);
01749             }
01750          } /* iIdent == IDENT_WORKSPACE */
01751          else
01752          {
01753             printf(
01754                "-E- unexpected header (%d) received from server\n",
01755                iIdent);
01756          }
01757 
01758          return -1;
01759 
01760       } /* (iIdent != IDENT_WORKSPACE) ) */
01761 
01762       /* receive work space info */
01763       iBuf = iAttrLen;
01764       pcc += HEAD_LEN;
01765       while(iBuf > 0)
01766       {
01767          if ( (iRC = recv( iSocket, pcc, iBuf, 0 )) < 0 )
01768          {
01769             perror("-E- receiving work space info");
01770             return -1;
01771          }
01772          iBuf -= iRC;
01773          pcc += iRC;
01774       } /* while(iBuf > 0) */
01775 
01776       if (iDebug)
01777          printf("    remainder work space buffer received (%d byte)\n",
01778                 iAttrLen);
01779 
01780       iWorkSizeAll = ntohl(pWorkSpace->iWorkSizeAll);
01781       iWorkFilesAll = ntohl(pWorkSpace->iWorkFilesAll);
01782       iWorkStatus = ntohl(pWorkSpace->iStatus);
01783       iWorkSizeSta = ntohl(pWorkSpace->iWorkSizeSta);
01784       iWorkFilesSta = ntohl(pWorkSpace->iWorkFilesSta);
01785       iWorkSizeStaTemp = ntohl(pWorkSpace->iWorkSizeStaTemp);
01786       iWorkFilesStaTemp = ntohl(pWorkSpace->iWorkFilesStaTemp);
01787       iWorkSizeEst = ntohl(pWorkSpace->iWorkSizeEst);
01788       iWorkFilesEst = ntohl(pWorkSpace->iWorkFilesEst);
01789 
01790       iWorkSizeStaRand = iWorkSizeSta - iWorkSizeStaTemp;
01791       iWorkFilesStaRand = iWorkFilesSta - iWorkFilesStaTemp;
01792 
01793       /* provide infos if stage of large workspace or if ws_query */
01794       if (iPoolInfo || (iAction == QUERY_WORKSPACE) || (iDebug) )
01795       {
01796          if (iDebug)
01797          {
01798             printf("    %d files, overall size %d MByte",
01799                    iWorkFilesAll, iWorkSizeAll);
01800             if (iWorkFilesEst)
01801                printf(", size estimated for %d files (%d MByte)\n",
01802                       iWorkFilesEst, iWorkSizeEst);
01803          }
01804 
01805          if (iWorkSizeSta == iWorkSizeAll)
01806          {
01807             if (iDebug)
01808             {
01809                printf(
01810                   "\n    all files already available on central disk\n");
01811                if ( (iPoolId == 2) &&
01812                     iWorkSizeStaRand &&
01813                     (iAction == QUERY_WORKSPACE) )
01814                   printf(
01815                      "    to get a guaranteed availability of %d days on disk pool use 'tsmcli stage'\n",
01816                      iPoolTempAvail);
01817             }
01818          }
01819          else if (iWorkSizeSta)
01820          {
01821             if (iDebug)
01822             {
01823                printf(
01824                   "\n    %d files already available on central disk (%d MByte)\n",
01825                   iWorkFilesSta, iWorkSizeSta);
01826                if (iWorkFilesStaTemp)
01827                   printf(
01828                      "    %d files already in %s (%d MByte)\n",
01829                      iWorkFilesStaTemp, cPoolNameTemp, iWorkSizeStaTemp);
01830                printf(
01831                   "    %d files still to be staged or currently being staged (%d MByte)\n",
01832                   iWorkFilesAll-iWorkFilesSta,
01833                   iWorkSizeAll - iWorkSizeSta);
01834             }
01835          }
01836          else if (iDebug)
01837             printf(", all to be staged\n");
01838 
01839          /* handle problems or limitations indicated by iWorkStatus:
01840             = 0: needed size ws available
01841             = 1: overall size ws > free size StagePool
01842             = 2: overall size ws > allowed size of ws
01843             = 3: needed size ws > size StagePool
01844             = 9: needed size ws > clean limit, but available: no sleep
01845             =10: needed size ws partially available,
01846                  sleep 10 min before start staging
01847             =20: needed size ws partially available,
01848                  sleep 20 min before start staging
01849          */
01850          if ( (iWorkStatus < 9) && (iWorkStatus != 0) )
01851          {
01852             if (iAction == QUERY_WORKSPACE)
01853                strcpy(cMsgPref, "-W-");
01854             else
01855                strcpy(cMsgPref, "-E-");
01856             printf("%s requested workspace '%s' cannot be staged:\n",
01857                    cMsgPref, pcGenFile);
01858 
01859             if (iWorkStatus < 0)
01860                printf("%s staging disk pool currently unavailable\n",
01861                       cMsgPref);
01862             else if (iWorkStatus == 1)
01863             {
01864                printf("    currently free in %s:   %d MByte\n",
01865                       cPoolNameTemp, iPoolTempFree);
01866                printf(
01867                   "    still needed:                  %d MByte (%d files)\n",
01868                   iWorkSizeAll-iWorkSizeSta,
01869                   iWorkFilesAll-iWorkFilesSta);
01870                if (iAction == QUERY_WORKSPACE)
01871                   printf( "-I- Check later again!\n");
01872                else printf(
01873                   "-I- Query work space status before retrying later!\n");
01874             }
01875             else if ( (iWorkStatus == 2) || (iWorkStatus == 3) )
01876             {
01877                if (iWorkStatus == 2) printf(
01878                   "%s max work space allowed in '%s' is currently limited to %d MByte\n",
01879                   cMsgPref, cPoolNameTemp, iPoolTempMaxWS);
01880                else printf(
01881                   "%s overall size of %s is limited to %d MByte\n",
01882                   cMsgPref, cPoolNameTemp, iPoolTempMax);
01883                printf(
01884                   "-I- Please reduce your work space requirements\n");
01885             }
01886             else if (iWorkStatus < 9)
01887                printf(
01888                   "-E- unexpected workspace status received from server (%d)\n",
01889                   iWorkStatus);
01890 
01891             if (iDebug)
01892                printf("-D- end %s\n\n", cModule);
01893             return -1;
01894 
01895          } /* (iWorkStatus < 9) && (iWorkStatus != 0) */
01896 
01897          if ( (iDebug) && (iWorkSizeSta != iWorkSizeAll) )
01898          {
01899             if (iAction == QUERY_WORKSPACE)
01900             {
01901                iWorkSizeNew = iWorkSizeAll - iWorkSizeSta;
01902                if (iRandomExcess)
01903                {
01904                   if (iWorkSizeNew > iHardwareFree)
01905                   {
01906                      printf("-D- currently unused in %s: %d MByte\n",
01907                             cPoolNameTemp, iPoolTempFree);
01908                      printf("    currently free in %s:   %d MByte, remainder temporarily used by other pools\n",
01909                             cPoolNameTemp, iHardwareFree);
01910                   }
01911                   else
01912                      printf("-D- currently free in %s:   %d MByte\n",
01913                             cPoolNameTemp, iHardwareFree);
01914                }
01915                else
01916                   printf("-D- currently free in %s:   %d MByte\n",
01917                          cPoolNameTemp, iPoolTempFree);
01918                printf(
01919                   "    to get all files on disk pool with a guaranteed availability of %d days:\n",
01920                   iPoolTempAvail);
01921                printf("    -> use 'tsmcli stage'\n");
01922 
01923             } /* (iAction == QUERY_WORKSPACE) */
01924         /*  else
01925                printf("-D- currently free in %s:   %d MByte\n",
01926                       cPoolNameTemp, iPoolTempFree);
01927          */
01928          } /* (iDebug) && (iWorkSizeSta != iWorkSizeAll) */
01929 
01930          /* server set clean request */
01931          if (iWorkStatus >= 9)
01932          {
01933             if (iDebug)
01934             {
01935                /* if (ntohl(pPoolInfoData->iFreeSize) >= 0)
01936                   does not work in Linux:
01937                   negative values are not recognized!            */
01938                ii = ntohl(pPoolInfoData0->iFreeSize);
01939 
01940                printf("-D- currently free (HW): %d MByte\n",
01941                       iHardwareFree);
01942                printf(
01943                   "    currently %d MByte unused in %s are allocated by other pools\n",
01944                   ii*(-1), cPoolNameTemp);
01945             }
01946 
01947             if (iAction == QUERY_WORKSPACE)
01948                strcpy(cMisc, "must be initiated (tsmcli stage)");
01949             else
01950                strcpy(cMisc, "is initiated");
01951             printf(
01952                "-I- a clean job %s to provide the requested space\n",
01953                cMisc);
01954 
01955             if (iWorkStatus > 9)
01956             {
01957                /* iSleepClean = iWorkStatus*60;     */     /* in sec */
01958                iSleepClean = iWorkStatus;
01959            /*  if (iDebug)
01960                   printf("-D- sleep for %ds\n", iSleepClean);
01961                sleep(iSleepClean);
01962             */
01963             }
01964 
01965          } /* (iWorkStatus >= 9) */
01966 
01967       } /* (iPoolInfo) || (iAction == QUERY_WORKSPACE) */
01968    } /* (iWorkSpaceInfo) */
01969 
01970    if (iDebug)
01971       printf("-D- end %s\n\n", cModule);
01972 
01973    return 0;
01974 
01975 } /* rawGetWSInfo */
01976 
01977 /********************************************************************
01978  * rawQueryFile: get query information for single file
01979  *
01980  * used for tape input handled sequentially
01981  * buffers for communication and query info allocated in calling
01982  *    procedure
01983  ********************************************************************
01984  */
01985 
01986 int rawQueryFile( int iSocket,
01987                   srawComm *pCommBuf,
01988                   void **pQueryBuf)
01989 {
01990    int iDebug = 0;
01991    char cModule[32] = "rawQueryFile";
01992    int iRC;
01993    int iIdent, iquery = -1, iAttrLen;
01994    int iStatus, iStatusLen;
01995    int iBuf, iBufComm;
01996    int ii;
01997    char *pc;
01998 
01999    srawComm *pComm;
02000    srawQueryResult *pQuery;
02001    srawObjAttr *pObjAttr;
02002 
02003    pComm = pCommBuf;
02004    pQuery = (srawQueryResult *) (*pQueryBuf);
02005 
02006    iBufComm = ntohl(pComm->iCommLen) + HEAD_LEN;
02007    if (iDebug) printf(
02008       "\n-D- begin %s: query file %s, action %d\n",
02009       cModule, pComm->cNamell, ntohl(pComm->iAction));
02010 
02011    switch( ntohl(pComm->iAction) )
02012    {
02013       case QUERY:
02014       case QUERY_ARCHIVE:
02015       case QUERY_ARCHIVE_RECORD:
02016       case QUERY_ARCHIVE_MGR:
02017       case QUERY_REMOVE:
02018       case QUERY_REMOVE_MGR:
02019       case QUERY_RETRIEVE:
02020       case QUERY_RETRIEVE_API:
02021       case QUERY_STAGE:
02022          ;                          /* okay */
02023          break;
02024       default:
02025          printf("-E- %s: invalid action %d\n",
02026                 cModule, ntohl(pComm->iAction));
02027          return -1;
02028    }
02029 
02030    pc = (char *) pComm;
02031    if ( (iRC = send( iSocket, pc, iBufComm, 0 )) < 0 )
02032    {
02033       printf("-E- %s: query file %s\n", cModule, pComm->cNamell);
02034       perror("    sending command buffer");
02035       return(-1);
02036    }
02037 
02038    if (iDebug) printf(
02039       "    query command sent to server (%d bytes), look for reply\n",
02040       iBufComm);
02041 
02042    /*********** look for reply from server *****************/
02043 
02044 gNextReply:
02045    pc = (char *) pQuery;
02046    iRC = rawRecvHead(iSocket, &pc);
02047    if (iRC <= 0)
02048    {
02049       printf("-E- %s: receiving buffer header with query information\n",
02050              cModule);
02051       return(-1);
02052    }
02053    else if (iDebug)
02054       printf("    %d bytes received\n", iRC);
02055 
02056    pc += HEAD_LEN;
02057    iIdent = ntohl(pQuery->iIdent);
02058    iquery = ntohl(pQuery->iObjCount);
02059    iAttrLen = ntohl(pQuery->iAttrLen);
02060 
02061    if ( (iIdent != IDENT_QUERY) && (iIdent != IDENT_QUERY_ARCHDB) )
02062    {
02063       if (iIdent == IDENT_STATUS)
02064       {
02065          iStatus = iquery;
02066          iStatusLen = iAttrLen;
02067          if ( (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) )
02068          {
02069             if (iDebug)
02070                printf("\n");
02071             printf("-E- %s: received error status from server",
02072                    cModule);
02073             if (iDebug)
02074                printf(" instead of query data:\n");
02075             else
02076                printf(":\n");
02077 
02078             if (iStatusLen > 0)
02079             {
02080                iRC = rawRecvError(iSocket, iStatusLen, &pc);
02081                if (iRC < 0) printf(
02082                   "-E- receiving error msg from server, rc = %d\n",
02083                   iRC);
02084                else printf("    %s\n", pc);
02085             }
02086             else printf("    no error message available\n");
02087 
02088          } /* iStatus == STA_ERROR || (iStatus == STA_ERROR_EOF) */
02089          else printf(
02090            "-E- %s: unexpected status (type %d) received from server\n",
02091            cModule, iStatus);
02092 
02093       } /* iIdent == IDENT_STATUS */
02094       else printf(
02095          "-E- %s: unexpected header (type %d) received from server\n",
02096          cModule, iIdent);
02097 
02098       return(-1);
02099 
02100    } /* iIdent != IDENT_QUERY  && != IDENT_QUERY_ARCHDB */
02101 
02102    if (iquery > 0)
02103    {
02104       for (ii=1; ii<=iquery; ii++)
02105       {
02106          pc = (char *) pQuery + HEAD_LEN;
02107          pObjAttr = (srawObjAttr *) pc;
02108          iBuf = iAttrLen;        /* only space for one object buffer */
02109          while(iBuf > 0)
02110          {
02111             if ( (iRC = recv( iSocket, pc, iBuf, 0 )) < 0 )
02112             {
02113                printf("-E- %s: receiving object buffer\n", cModule);
02114                perror("-E- receiving query results");
02115                return -1;
02116             }
02117             iBuf -= iRC;
02118             pc += iRC;
02119          } /* while(iBuf > 0) */
02120 
02121          if (iDebug)
02122          {
02123             if (ii == 1) printf(
02124                "    query buffer received (%d bytes)\n", iAttrLen);
02125             else printf(
02126                "    query buffer overlaid (%d bytes)\n", iAttrLen);
02127             printf("    cNamell %s, iObjLow %d",
02128                    pObjAttr->cNamell, ntohl(pObjAttr->iObjLow));
02129             if (iIdent == IDENT_QUERY)
02130                printf(" (TSM DB)\n");
02131             else
02132                printf(" (ArchivePool)\n");
02133          }
02134       } /* object loop */
02135    } /* (iquery > 0) */
02136    else if (iIdent == IDENT_QUERY)        /* nothing found in TSM DB */
02137          goto gNextReply;                   /* check for ArchivePool */
02138 
02139    switch (iquery)
02140    {
02141       case 0:
02142          if (iDebug)
02143             printf("    no matching object %s found\n", pComm->cNamell);
02144          break;
02145       case 1:
02146          if (iDebug)
02147             printf("    file %s already archived\n", pComm->cNamell);
02148          break;
02149       default:
02150          if ( (iquery > 1) && (strcmp(pComm->cOwner, "goeri") == 0) )
02151             printf("-W- %d versions of %s exist!\n",
02152                    iquery, pComm->cNamell);
02153          else
02154          {
02155             printf("-E- %s: invalid number %d of objects %s found\n",
02156                    cModule, iquery, pComm->cNamell);
02157             iquery = -1;
02158          }
02159    } /* switch (iquery) */
02160 
02161    if (iDebug) printf(
02162       "-D- end %s\n\n", cModule);
02163 
02164    return iquery;
02165 
02166 } /* end rawQueryFile */
02167 
02168 /********************************************************************
02169  * rawQueryList: get query information from list of files
02170  *
02171  * created 21. 2.2001 by Horst Goeringer
02172  ********************************************************************
02173  */
02174 
02175 int rawQueryList( int iSocket,
02176     char *pFile,                       /* generic name of file list */
02177     int iFilenoReq,          /* no. of requ. file (1 .. n), init: 0 */
02178     int iFull,                                   /* verbosity level */
02179     char *pInfo) /* query info of requested file (init: first file) */
02180 {
02181    int iDebug = 0;
02182    char cModule[32] = "rawQueryList";
02183    int iRC;
02184    int iIdent;
02185    int iAttrLen;
02186 
02187    int iFileno;                               /* no. of files found */
02188    int iquery = -1;         /* no. of files in current query buffer */
02189    int iqueryBuf = 0;              /* no. of query buffers received */
02190 
02191    int iBuffer;                       /* size query buffer in bytes */
02192 
02193    int iStatus, iStatusLen;
02194    int iBuf, iBufComm;
02195 
02196    int ii;
02197    char *pcc;
02198    bool_t bQDone = bFalse;
02199 
02200    char cNamefs[MAX_OBJ_FS] = "", *pcNamefs;      /* filespace name */
02201    char cNamehl[MAX_OBJ_HL] = "", *pcNamehl;     /* high level name */
02202    char cNamell[MAX_OBJ_LL] = "", *pcNamell;     /* low  level name */
02203 
02204    char cOwner[DSM_MAX_OWNER_LENGTH] = "";
02205    char cliNode[MAX_NODE] = "";
02206 
02207    int iCommSize = sizeof(srawComm); /* client/server communication */
02208    srawComm *pComm, sComm;
02209 
02210    pComm = &sComm;
02211 
02212    pcNamefs = cNamefs;
02213    pcNamehl = cNamehl;
02214    pcNamell = cNamell;
02215 
02216    if (iDebug)
02217       printf("\n-D- this is %s\n", cModule);
02218 
02219    pComm->iIdent = htonl(IDENT_COMM);
02220    pComm->iAction = htonl(QUERY);
02221    pComm->iCommLen = htonl(iCommSize - HEAD_LEN);
02222    pComm->iBufsizeFile = htonl(0);
02223 
02224    /******************** allocate query buffer **********************/
02225 
02226    if (iFilenoReq > 0)
02227    {
02228       if (pQueryBuffer == 0)
02229       {
02230          printf("-W- assume initial call for file list %s\n", pFile);
02231          iFilenoReq = 0;
02232       }
02233    }
02234 
02235    if (iFilenoReq <= 0)
02236    {
02237       iBuffer = MBUF_SOCK;
02238       iqueryMax = (iBuffer - HEAD_LEN)/sizeof(srawObjAttr);
02239       /* iqueryMax = 3;        DDD must be synchronized with server */
02240 
02241       if ( (pQueryBuffer =
02242            (char *) calloc(iBuffer, sizeof(char))) == NULL )
02243       {
02244          perror("-E- allocating data buffer");
02245          printf("-E- allocating data buffer (size %d)\n", iBuffer);
02246          return 1;
02247       }
02248       if (iDebug)
02249       {
02250          printf("-D- data buffer allocated (size %d)\n", iBuffer);
02251          printf("    max %d queries per buffer\n", iqueryMax);
02252       }
02253       pQueryResult = (srawQueryResult *) pQueryBuffer;
02254       pQueryObj = &(pQueryResult->objAttr);
02255       pQueryObj0 = pQueryObj;  /* keep ptr to attributes first file */
02256 
02257    } /* iFilenoReq <= 0 */
02258    else
02259    {
02260       if (iFilenoReq > iqueryMax)
02261       {
02262          printf("-E- max %d file infos kept, please restrict your filelist %s\n",
02263                 iqueryMax, pFile);
02264          return -9;
02265       }
02266 
02267       pQueryObj = pQueryObj0;   /* set ptr to attributes first file */
02268       for (ii=1; ii<iFilenoReq; ii++)
02269       {
02270          pQueryObj++;
02271       }
02272 
02273       iRC = rawQueryString(pQueryObj, iFull, pInfo);
02274       if (iDebug) printf(
02275          "-D- requested file no %d found:\n    %s", iFilenoReq, pInfo);
02276       goto gDone;
02277    }
02278 
02279    /******************** get ADSM representation ********************/
02280 
02281    strcpy(pcNamefs, pFile);
02282    pcc = (char *) strchr(pcNamefs, *pcObjDelim);
02283    if (pcc == NULL)
02284    {
02285       printf("-E- invalid remote file name '%s'\n", pFile);
02286       return -1;
02287    }
02288 
02289    if (strncmp(pcc, pFile, 1) == 0)      /* skip leading delimiter */
02290       pcc++;
02291    pcc = (char *) strchr(pcc, *pcObjDelim);
02292    if (pcc == NULL)
02293    {
02294       printf("-E- invalid remote file name '%s'\n", pFile);
02295       return -1;
02296    }
02297    strcpy(pcNamehl, pcc);     /* starts with high level object name */
02298    strncpy(pcc, "\0", 1);                     /* terminates FS name */
02299 
02300    pcc = pcNamehl;
02301    pcc++;                                 /* skip leading delimiter */
02302    pcc = (char *) strrchr(pcc, *pcObjDelim);
02303    if (pcc == NULL)
02304    {
02305       printf("-E- invalid remote file name '%s'\n", pFile);
02306       return -1;
02307    }
02308    strcpy(pcNamell, pcc);      /* starts with low level object name */
02309    strncpy(pcc, "\0", 1);      /* terminates high level object name */
02310 
02311    if (iDebug)
02312       printf("    FS name '%s', HL name '%s', LL name '%s'\n",
02313              pcNamefs, pcNamehl, pcNamell);
02314 
02315    strcpy(pComm->cNamefs, (char *) rawGetFSName(pcNamefs));
02316    if (strlen(pComm->cNamefs) == 0)
02317       return -1;
02318 
02319    strcpy(pComm->cNamehl, (char *) rawGetHLName(pcNamehl));
02320    /* strcpy(pComm->cNamell, (char *) rawGetLLName(pcNamell)); */
02321    iRC = rawGetLLName(pcNamell, pcObjDelim, pComm->cNamell);
02322 
02323    if (iDebug)
02324       printf("    FS name '%s', HL name '%s', LL name '%s'\n",
02325              pComm->cNamefs, pComm->cNamehl, pComm->cNamell);
02326 
02327    /***************** get client info, contact server ***************/
02328 
02329    strcpy(cOwner, (char *) rawGetUserid());
02330    iRC = gethostname(cliNode, MAX_NODE);
02331    if (iRC)
02332    {
02333       printf("-E- getting client host name: %s\n", strerror(iRC));
02334       return -1;
02335    }
02336 
02337    if (iDebug)
02338       printf("    user %s on node %s, platform %s\n",
02339              cOwner, cliNode, cOS);            /* cOS from rawcli.h */
02340 
02341    strcpy(pComm->cApplType, cApplType);
02342    strcpy(pComm->cOwner,  cOwner);
02343    strcpy(pComm->cliNode, cliNode);
02344    strcpy(pComm->cOS, cOS);
02345 
02346    pcc = (char *) pComm;
02347    if ( (iRC = send( iSocket, pcc, iCommSize, 0 )) < 0 )
02348    {
02349       printf("-E- %s: query file %s\n", cModule, pComm->cNamell);
02350       perror("    sending command buffer");
02351       return -1;
02352    }
02353 
02354    if (iDebug) printf(
02355       "-D- query command sent to server (%d bytes), look for reply\n",
02356       iCommSize);
02357 
02358    /******************** look for reply from server *****************/
02359 
02360    while (!bQDone)                       /* loop over query buffers */
02361    {
02362       pcc = (char *) pQueryResult;
02363       iRC = rawRecvHead(iSocket, &pcc);
02364       if (iRC <= 0)
02365       {
02366          printf("-E- receiving buffer header with query information\n");
02367          return(-1);
02368       }
02369       else if (iDebug > 0) printf("    %d bytes received\n", iRC);
02370 
02371       pcc += HEAD_LEN;
02372       iIdent = ntohl(pQueryResult->iIdent);
02373       iquery = ntohl(pQueryResult->iObjCount);
02374       iAttrLen = ntohl(pQueryResult->iAttrLen);
02375 
02376       if (iIdent != IDENT_QUERY)
02377       {
02378          if (iIdent == IDENT_STATUS)
02379          {
02380             iStatus = iquery;
02381             iStatusLen = iAttrLen;
02382             if ( (iStatus == STA_ERROR) || (iStatus == STA_ERROR_EOF) )
02383             {
02384                if (iDebug) printf("\n");
02385                printf("-E- received error status from server");
02386                if (iDebug)
02387                   printf(" instead of query data:\n");
02388                else printf(":\n");
02389 
02390                if (iStatusLen > 0)
02391                {
02392                   iRC = rawRecvError(iSocket, iStatusLen, &pcc);
02393                   if (iRC < 0) printf(
02394                      "-E- receiving error msg from server, rc = %d\n",
02395                      iRC);
02396                   else printf("    %s\n", pcc);
02397                }
02398                else printf("    no error message available\n");
02399 
02400             } /* iStatus == STA_ERROR || (iStatus == STA_ERROR_EOF) */
02401             else printf(
02402               "-E- unexpected status (type %d) received from server\n",
02403               iStatus);
02404 
02405          } /* iIdent == IDENT_STATUS */
02406          else printf(
02407             "-E- unexpected header (type %d) received from server\n",
02408             iIdent);
02409 
02410          return -1;
02411 
02412       } /* iIdent != IDENT_QUERY */
02413 
02414       if (iquery == 0)
02415       {
02416          bQDone = bTrue;
02417          if (iQueryCount == 0)
02418             printf("-I- no matching objects found\n");
02419          else
02420             if (iDebug) printf("    no more objects\n");
02421 
02422       } /* (iquery == 0) */
02423       else
02424       {
02425          iBuf = iquery*iAttrLen;
02426          iBufComm = iBuf;
02427          while(iBuf > 0)
02428          {
02429             if ( (iRC = recv( iSocket, pcc, iBuf, 0 )) < 0 )
02430             {
02431                perror("-E- receiving query results");
02432                return -1;
02433             }
02434             iBuf -= iRC;
02435             pcc += iRC;
02436          } /* while(iBuf > 0) */
02437 
02438          iqueryBuf++;
02439 
02440          if (iDebug) printf(
02441             "*** query buffer %d (%d bytes): %d objects\n",
02442                             iqueryBuf, iBufComm, iquery);
02443 
02444          if (iquery < iqueryMax)
02445          {
02446             bQDone = bTrue;
02447             if (iDebug)
02448                printf("    query finished\n");
02449          }
02450          else if (iDebug)
02451             printf("    possibly more query buffers outstanding\n");
02452 
02453          /************** handle buffer with query results ************/
02454 
02455          /* loop over objects of current query buffer */
02456          pQueryObj = pQueryObj0; /* set ptr to first object in buffer */
02457          for (ii=1; ii<=iquery; ii++)
02458          {
02459             iQueryCount++;                  /* no. of current object */
02460             if (iDebug)
02461             {
02462                iRC = rawQueryString(pQueryObj, iFull, pInfo);
02463                printf("%d: %s", iQueryCount, pInfo);
02464             }
02465             pQueryObj++;                /* points now to next object */
02466 
02467          } /* loop over objects of current query buffer */
02468       } /* (iquery > 0) */
02469 
02470    } /* while (!bQDone) */
02471 
02472 gDone:
02473    if (iDebug)
02474    {
02475       if (iFilenoReq == 0)
02476          printf("-D- %d matching objects %s%s%s found\n",
02477                 iQueryCount,
02478                 pComm->cNamefs,
02479                 pComm->cNamehl,
02480                 pComm->cNamell);
02481 
02482       printf("-D- end %s\n\n", cModule);
02483    }
02484 
02485    if ( (iQueryCount) && (iFilenoReq == 0) )
02486       iRC = rawQueryString(pQueryObj0, iFull, pInfo);
02487 
02488    return iQueryCount;
02489 
02490 } /* end rawQueryList */
02491 
02492 /**********************************************************************
02493  * rawScanObjbuf:
02494  *   check if obj already available in obj buffer chain
02495  * created 10. 7.2003 by Horst Goeringer
02496  **********************************************************************
02497  */
02498 
02499 int rawScanObjbuf(char *pcFile, int iObjnoMax, int *piObjBuf0)
02500 {
02501    int iDebug = 0;
02502    char cModule[32] = "rawScanObjbuf";
02503    int ii, jj = 0;
02504    int iFound = 0;   /* =1: specified file already available in list */
02505    int iObjnoBuf;                /* no. of objects in current buffer */
02506    int iObjnoAll = 0;               /* sum of objects in all buffers */
02507    int iBufno = 0;                          /* no. of object buffers */
02508    int *piObjBuf;                    /* ptr to current object buffer */
02509    int **ppiNextBuf;
02510 
02511    srawRetrList *psRetrList;     /* points to object in buffer chain */
02512 
02513    if (iDebug)
02514       printf("\n-D- begin %s: check for %s\n", cModule, pcFile);
02515 
02516    piObjBuf = piObjBuf0;
02517    /* loop over object buffers */
02518    for (;;)
02519    {
02520       iObjnoBuf = *piObjBuf;
02521       psRetrList = (srawRetrList *) &(piObjBuf[1]);
02522       iBufno++;
02523 
02524       /* loop over objects in current buffer */
02525       for (ii=1; ii<=iObjnoBuf; ii++)
02526       {
02527          jj++;
02528          if (iDebug == 2)
02529             printf("    %d: %s\n", jj, psRetrList->cNamell);
02530 
02531          if (strcmp(pcFile, psRetrList->cNamell) == 0)
02532          {
02533             if (iDebug) printf(
02534                "    file %s already available in list\n", pcFile);
02535             iFound = 1;
02536             goto gEndScan;
02537          }
02538 
02539          psRetrList++;
02540 
02541       } /* loop over objects in current buffer */
02542 
02543       if (iObjnoBuf < iObjnoMax)                      /* last buffer */
02544          break;
02545 
02546       if (psRetrList)
02547       {
02548          ppiNextBuf = (int **) psRetrList;
02549          piObjBuf = *ppiNextBuf;
02550          psRetrList = (srawRetrList *) &(piObjBuf[1]);
02551       }
02552       else                                            /* last buffer */
02553          break;
02554 
02555    } /* loop over buffers */
02556 
02557 gEndScan:
02558    if (iDebug)
02559       printf("-D- end %s: %d buffers scanned\n\n", cModule, iBufno);
02560 
02561    if (iFound)
02562       return 1;
02563    else
02564       return 0;
02565 
02566 } /* end rawScanObjbuf */
02567 
02568 #ifdef _AIX
02569 /*********************************************************************
02570  * ielpst: Elapsed (wall-clock) time measurement
02571  *
02572  *    Usage examples:
02573  *
02574  *  ielpst( 1, iBuf[0..1] );
02575  *  ... code ...
02576  *  ElapsedTime(in microsecs) = ielpst( 1, iBuf[0..1] );
02577  *
02578  *  ielpst( 1000, iBuf[0..1] );
02579  *  ... code ...
02580  *  ElapsedTime(in millisecs) = ielpst( 1000, iBuf[0..1] );
02581  *
02582  *********************************************************************
02583  * created 17.11.1992, Michael Kraemer
02584  *********************************************************************
02585  */
02586 
02587 unsigned long ielpst( unsigned long iScale,
02588                       unsigned long *iBuf )
02589 {
02590    int iDebug = 0;
02591    char cModule[32] = "ielpst";
02592    struct timestruc_t stv;
02593    unsigned long iTemp[2];
02594 
02595    gettimer( TIMEOFDAY, &stv );
02596 
02597    if ( iScale <= 0 ) iScale = 1;
02598    iTemp[1] = stv.tv_sec  - iBuf[1];
02599    if ( ( iTemp[0] = stv.tv_nsec - iBuf[0] ) & 0x80000000 ) {
02600       iTemp[0] += 1000000000L; iTemp[1] -= 1;
02601    }
02602    iBuf[1] = stv.tv_sec; iBuf[0] = stv.tv_nsec;
02603    return( iTemp[1] * ( 1000000L / iScale ) + ( iTemp[0] / 1000 ) / iScale );
02604 
02605 } /* ielpst */
02606 
02607 /* FORTRAN entry */
02608 unsigned long ielpst_( unsigned long *iScale,
02609                        unsigned long *iBuf )
02610 {
02611    return( ielpst( *iScale, iBuf ) );
02612 } /* ielpst_ */
02613 #endif
02614 
02615 
02616 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Tue Nov 8 10:56:09 2005 for Go4-v2.10-5 by doxygen1.2.15