home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / partvw.exe / PARTVIEW.C next >
Text File  |  1994-11-29  |  24KB  |  1,021 lines

  1. /****************************************************************************
  2. **    File:    PARTVIEW.C
  3. **
  4. **    Desc:    This program discovers all of the File Servers in a tree, lists the
  5. **           partitions (replicas) on each and connects to each server to read
  6. **            the current Synchronized Up To value.
  7. **
  8. **
  9. **
  10. **        DISCLAIMER
  11. **
  12. **    Novell, Inc. makes no representations or warranties with respect to
  13. **    any NetWare software, and specifically disclaims any express or
  14. **    implied warranties of merchantability, title, or fitness for a
  15. **    particular purpose.
  16. **
  17. **    Distribution of any NetWare software is forbidden without the
  18. **    express written consent of Novell, Inc.  Further, Novell reserves
  19. **    the right to discontinue distribution of any NetWare software.
  20. **
  21. **    Novell is not responsible for lost profits or revenue, loss of use
  22. **    of the software, loss of data, costs of re-creating lost data, the
  23. **    cost of any substitute equipment or program, or claims by any party
  24. **    other than you.  Novell strongly recommends a backup be made before
  25. **    any software is installed.   Technical support for this software
  26. **    may be provided at the discretion of Novell.
  27. **
  28. **    Programmers:
  29. **
  30. **        Ini    Who                        Firm
  31. **        -----------------------------------------------------------------------
  32. **        KLB    Karl Bunnell                Novell Developer Support.
  33. **
  34. **    History:
  35. **
  36. **        When        Who    What
  37. **        -----------------------------------------------------------------------
  38. **        10-28-94    klb    First code.
  39. */
  40.  
  41. /****************************************************************************
  42. **    Include headers, macros, function prototypes, etc.
  43. */
  44.  
  45.     /*------------------------------------------------------------------------
  46.     **    MACROS
  47.     */
  48.     #define NWDOS
  49.  
  50.     /*------------------------------------------------------------------------
  51.     **    ANSI
  52.     */
  53.     #include <stdlib.h>
  54.     #include <stdio.h>
  55.     #include <string.h>
  56.     #include <conio.h>
  57.     #include <dos.h>
  58.     #include <time.h>
  59.  
  60.     /*------------------------------------------------------------------------
  61.     **    NetWare
  62.     */
  63.     #include <nwnet.h>
  64.     #include <nwcalls.h>
  65.     #include <nwlocale.h>
  66.     #include "partview.h"
  67.  
  68.  
  69.     /*------------------------------------------------------------------------
  70.     **    Prototypes
  71.     */
  72.     int ActOnData(NWDS_BUFFER NWFAR *buffer);
  73.     int SearchForObjects(void);
  74.     ReadPartInfo(char        *serverName);
  75.     ReadSyncTimes(char *serverName, char *partName, struct PartRecord *ptrthis);
  76.     DisplayRetrievedInfo(void);
  77.     GetReplicaDescription(NWREPLICA_TYPE replicaType, char *replicaDesc);
  78.     FreeUpList(void);
  79.  
  80.     /*------------------------------------------------------------------------
  81.     **    Globals
  82.     */
  83.     NWDSContextHandle    dContext;
  84.    NWCOUNT            objectCount;
  85.     struct ServerRecord        *pfirst=NULL, *pthis=NULL, *pnew=NULL;
  86.  
  87.  
  88. /****************************************************************************
  89. ** Function: Main (void)
  90. */
  91.  
  92. void main(void)
  93. {
  94.     NWDSCCODE            cCode;
  95.     LCONV                lconvInfo;
  96.     DWORD                    flags;
  97.     char far             *countryPtr;
  98.  
  99.     cCode = NWCallsInit(NULL, NULL);
  100.     if (cCode)
  101.         {
  102.         printf("\nCall to NWCallsInit returned: %04X", cCode);
  103.         exit(1);
  104.         }
  105.  
  106.     countryPtr = NWLsetlocale(LC_ALL, "");
  107.  
  108.     NWLlocaleconv(&lconvInfo);
  109.  
  110.     cCode = NWInitUnicodeTables(lconvInfo.country_id, lconvInfo.code_page);
  111.  
  112.     if(cCode)
  113.         {
  114.         printf("NWInitUnicodeTables() returned: %04X\n", cCode);
  115.         goto _FreeUnicodeTables;
  116.         }
  117.  
  118.     dContext = NWDSCreateContext();
  119.  
  120.     if (dContext == ERR_CONTEXT_CREATION)
  121.         {
  122.         printf("NWDSCreateContext returned: %04X\n", cCode);
  123.         goto _FreeContext;
  124.         }
  125.  
  126.  
  127.     /*-------------------------------------------------------------------
  128.    ** Get the current directory context flags so we can modify them.
  129.     */
  130.  
  131.    cCode = NWDSGetContext(
  132.                 /* Contxt Handle    */ dContext,
  133.                 /* Key              */ DCK_FLAGS,
  134.                 /* Context Flags    */ &flags
  135.                 );
  136.  
  137.     if (cCode < 0)
  138.         {
  139.         printf("NWDSGetContext returned: %04X\n", cCode);
  140.         goto _FreeContext;
  141.         }
  142.  
  143.     /*-------------------------------------------------------------------
  144.    **   Turn typeless naming on.
  145.    **   Turn canonicalize names off.  This means we will get full names.
  146.    */
  147.  
  148.    flags |= DCV_TYPELESS_NAMES;
  149.    flags &= ~DCV_CANONICALIZE_NAMES;
  150.  
  151.     /*-------------------------------------------------------------------
  152.    ** Set the directory context flags so they take effect.
  153.     */
  154.  
  155.    cCode = NWDSSetContext(
  156.                 /* Context Handle */ dContext,
  157.                 /* Key            */ DCK_FLAGS,
  158.                 /* Set Flag Value */ &flags
  159.                 );
  160.  
  161.     if (cCode < 0)
  162.         {
  163.         printf("NWDSSetContext returned: %04X\n", cCode);
  164.         goto _FreeContext;
  165.         }
  166.  
  167.     SearchForObjects();
  168.     DisplayRetrievedInfo();
  169.  
  170.     FreeUpList();
  171.  
  172. _FreeContext:
  173.     NWDSFreeContext(dContext);
  174. _FreeUnicodeTables:
  175.     NWFreeUnicodeTables();
  176.  
  177.  
  178. }
  179.  
  180.  
  181.  
  182. /****************************************************************************
  183. ** Function: int SearchForObjects(void)
  184. **    This function initializes the search filter and issues the request to
  185. ** return all attributes that meet the search criteria and the time stamp
  186. ** criteria.
  187. */
  188.  
  189. int SearchForObjects(void)
  190. {
  191.  
  192.    NWFLAGS           searchAliases = FALSE,
  193.              allAttrs = FALSE;
  194.    NWDS_TYPE         infoType = 0;
  195.    NWDS_ITERATION    iterHandle = (NWDS_ITERATION)-1;
  196.    NWDS_BUFFER NWFAR *searchFilter = NULL,
  197.             NWFAR *attrNames = NULL,
  198.            NWFAR *retBuf = NULL;
  199.     NWDSCCODE            cCode;
  200.    NWDS_NUM_OBJ      cntObjectsToSearch,
  201.              cntObjectsSearched;
  202.    int               i,
  203.              iterCnt = 0,
  204.                             err=0;
  205.    void        NWFAR *val;
  206.    NWSYNTAX_ID       syntaxID;
  207.    NWDS_FILTER_CURSOR NWFAR *cur = NULL;
  208.  
  209.  
  210.    /*------------------------------------------------------------
  211.    ** Allocate a buffer to contain the search expression
  212.     */
  213.     cCode = NWDSAllocBuf(
  214.                 /* Buffer Size */ DEFAULT_MESSAGE_LEN,
  215.                 /* Buff. Point.*/ &searchFilter
  216.                 );
  217.  
  218.     if (cCode < 0)
  219.             {
  220.             printf("NWDSAllocBuf returned: %04X\n", cCode);
  221.             goto Out;
  222.             }
  223.  
  224.    /*------------------------------------------------------------
  225.    ** Initialize the searchFilter buffer
  226.     */
  227.    cCode = NWDSInitBuf(
  228.                 /* Context  */ dContext,
  229.                 /* Operation*/ DSV_SEARCH_FILTER,
  230.                 /* buffer   */ searchFilter
  231.                 );
  232.  
  233.  
  234.     if (cCode < 0)
  235.             {
  236.             printf("NWDSInitBuf returned: %04X\n", cCode);
  237.             goto Out;
  238.             }
  239.  
  240.    /*------------------------------------------------------------
  241.    ** Allocate a filter cursor to put the search expression
  242.     */
  243.    cCode = NWDSAllocFilter(
  244.                 /* Cursor    */ &cur
  245.                 );
  246.  
  247.     if (cCode < 0)
  248.             {
  249.             printf("NWDSAllocFilter returned: %04X\n", cCode);
  250.             goto Out;
  251.             }
  252.  
  253.    /*------------------------------------------------------------ 
  254.    ** Now we can build the expression tree.
  255.     ** Filter on Object Class of "User".
  256.     */
  257.  
  258.    cCode = NWDSAddFilterToken(
  259.                 /* Cursor (exp tree) */ cur,
  260.                 /* TOKEN             */ FTOK_ANAME,
  261.                 /* Name or Value     */ "Object Class",
  262.                 /* Syntax ID         */ SYN_CLASS_NAME
  263.                 );
  264.  
  265.     if (cCode < 0)
  266.             {
  267.               printf("NWDSAddFilterToken returned: %04X\n", cCode);
  268.             goto Out;
  269.             }
  270.  
  271.    cCode = NWDSAddFilterToken(
  272.                 /* Cursor (exp tree) */ cur,
  273.                 /* TOKEN             */ FTOK_EQ,
  274.                 /* Name or Value     */ NULL,
  275.                 /* Syntax ID         */ 0
  276.                 );
  277.  
  278.     if (cCode < 0)
  279.             {
  280.             printf("NWDSAddFilterToken returned: %04X\n", cCode);
  281.             goto Out;
  282.             }
  283.  
  284.  
  285.    cCode = NWDSAddFilterToken(
  286.                 /* Cursor (exp tree) */ cur,
  287.                 /* TOKEN             */ FTOK_AVAL,
  288.                 /* Name or Value     */ "NCP Server",
  289.                 /* Syntax ID         */ SYN_CLASS_NAME
  290.                 );
  291.  
  292.     if (cCode < 0)
  293.             {
  294.               printf("NWDSAddFilterToken returned: %04X\n", cCode);
  295.             goto Out;
  296.             }
  297.  
  298.  
  299.  
  300.    cCode = NWDSAddFilterToken(
  301.                 /* Cursor (exp tree) */ cur,
  302.                 /* TOKEN             */ FTOK_AND,
  303.                 /* Name or Value     */ NULL,
  304.                 /* Syntax ID         */ 0
  305.                 );
  306.  
  307.     if (cCode < 0)
  308.             {
  309.             printf("NWDSAddFilterToken returned: %04X\n", cCode);
  310.             goto Out;
  311.             }
  312.  
  313.  
  314.    cCode = NWDSAddFilterToken(
  315.                 /* Cursor (exp tree) */ cur,
  316.                 /* TOKEN             */ FTOK_ANAME,
  317.                 /* Name or Value     */ "Version",
  318.                 /* Syntax ID         */ SYN_CI_STRING
  319.                 );
  320.  
  321.     if (cCode < 0)
  322.             {
  323.               printf("NWDSAddFilterToken returned: %04X\n", cCode);
  324.             goto Out;
  325.             }
  326.  
  327.  
  328.    cCode = NWDSAddFilterToken(
  329.                 /* Cursor (exp tree) */ cur,
  330.                 /* TOKEN             */ FTOK_EQ,
  331.                 /* Name or Value     */ NULL,
  332.                 /* Syntax ID         */ 0
  333.                 );
  334.  
  335.     if (cCode < 0)
  336.             {
  337.             printf("NWDSAddFilterToken returned: %04X\n", cCode);
  338.             goto Out;
  339.             }
  340.  
  341.  
  342.    cCode = NWDSAddFilterToken(
  343.                 /* Cursor (exp tree) */ cur,
  344.                 /* TOKEN             */ FTOK_AVAL,
  345.                 /* Name or Value     */ "Novell Netware 4*",
  346.                 /* Syntax ID         */ SYN_CI_STRING
  347.                 );
  348.  
  349.     if (cCode < 0)
  350.             {
  351.               printf("NWDSAddFilterToken returned: %04X\n", cCode);
  352.             goto Out;
  353.             }
  354.  
  355.  
  356.    cCode = NWDSAddFilterToken(
  357.                 /* Cursor (exp tree) */ cur,
  358.                 /* TOKEN             */ FTOK_END,
  359.                 /* Name or Value     */ NULL,
  360.                 /* Syntax ID         */ 0
  361.                 );
  362.  
  363.     if (cCode < 0)
  364.             {
  365.             printf("NWDSAddFilterToken returned: %04X\n", cCode);
  366.             goto Out;
  367.             }
  368.  
  369.     /*-------------------------------------------------------------
  370.    ** The expression is complete! Put the filter expression 
  371.    ** into the filter buffer.  The freeVal function pointer
  372.    ** would free the attribute values, but we allocated the
  373.    ** values on the stack, so pass NULL.
  374.    */
  375.  
  376.    cCode = NWDSPutFilter(
  377.                 /* Context Handle */ dContext,
  378.                 /* Input Buffer   */ searchFilter,
  379.                 /* Cursor Pointer */ cur,
  380.                 /* Free val. func */ NULL
  381.                 );
  382.  
  383.     if (cCode < 0)
  384.             {
  385.               printf("NWDSAddFilterToken returned: %04X\n", cCode);
  386.             goto Out;
  387.             }
  388.  
  389.    else
  390.       cur = NULL; /* so we know at the bottom of this routine to free or not */
  391.  
  392.     /*-------------------------------------------------------------
  393.     ** Allocate a buffer to receive the results.
  394.     */
  395.     cCode = NWDSAllocBuf(
  396.                 /* Buffer Size */ DEFAULT_MESSAGE_LEN,
  397.                 /* Buff. Point.*/ &retBuf
  398.                 );
  399.  
  400.     if (cCode < 0)
  401.             {
  402.               printf("NWDSAllocBuf returned: %04X\n", cCode);
  403.             goto Out;
  404.             }
  405.  
  406.    do
  407.    {
  408.         /*---------------------------------------------------------
  409.       ** Finally! we have everything we need to search. Note that
  410.         ** the base object specified here is "[Root]". The base
  411.         ** object could be an OU. This will initiate the search from
  412.         ** that OU on down the tree.
  413.         */
  414.       cCode = NWDSSearch(
  415.                 /* Context handle */ dContext,
  416.                 /* Base Obj Name  */ "[Root]",
  417.             /* Scope          */ DS_SEARCH_SUBTREE,
  418.                 /* Search Alias?  */ searchAliases,
  419.                 /* Search Filter  */ searchFilter,
  420.                 /* Info Type      */ infoType,
  421.                 /* All Attrib's ? */ allAttrs,
  422.                 /* Attrib. names  */ attrNames,
  423.                 /* Iter. Handle   */ &iterHandle,
  424.             /* cnt Obj's 2 sch*/ cntObjectsToSearch,
  425.                 /* cnt obj's schd */ &cntObjectsSearched,
  426.                 /* Object returned*/ retBuf
  427.                 );
  428.  
  429.         if (cCode < 0)
  430.                 {
  431.                   printf("NWDSExtSyncSearch returned: %04X\n", cCode);
  432.                 goto Out;
  433.                 }
  434.  
  435.       iterCnt++;
  436.       err = ActOnData(retBuf);
  437.  
  438.    }
  439.    while (iterHandle != (NWDS_ITERATION)-1);
  440.  
  441. // printf("\n\n%d iterations of search\n", iterCnt);
  442.  
  443. Out:
  444.    if (retBuf)
  445.       NWDSFreeBuf(retBuf);
  446.    if (cur)
  447.       NWDSFreeFilter(cur, NULL);
  448.    if (searchFilter)
  449.       NWDSFreeBuf(searchFilter);
  450.    if (attrNames)
  451.       NWDSFreeBuf(attrNames);
  452.  
  453.     return(0);
  454. }
  455.  
  456.  
  457. /****************************************************************************
  458. ** Function: int ActOnData(NWDS_BUFFER NWFAR *buffer)
  459. **    The buffer returned from NWDSSearch() is passed to this function. This
  460. ** buffer contains all of the object/attribute information that met the
  461. ** criteria of the search. This function reads this information from the
  462. ** buffer.
  463. */
  464. int ActOnData(NWDS_BUFFER NWFAR *buffer)
  465. {
  466.     NWDSCCODE            dscCode;
  467.     NWCCODE                cCode;
  468.     NWCOUNT               attrCount,
  469.                             attrValCount;
  470.    NWOBJECT_INFO      objectInfo;
  471.    static char            objectName[MAX_DN_CHARS + 1];
  472.     char                    shortName[48];
  473.     int                    err=1,
  474.                             i;
  475.     NWNUMBER                maxConnections;
  476.  
  477.  
  478.     dscCode = NWDSGetObjectCount(
  479.                 /* Req. Context   */ dContext,
  480.                 /* P. to read buf.*/ buffer,
  481.                 /* Num. of OBJs   */ &objectCount
  482.                 );
  483.  
  484.     if (dscCode < 0)
  485.         {
  486.         printf("\nNWDSGetObjectCount returned : %04X\n", dscCode);
  487.         return(err);
  488.         }
  489.  
  490.     NWGetMaximumConnections(
  491.         /* max connections   */ &maxConnections
  492.         );
  493.  
  494.  
  495.     printf("\nMax connections: %d", maxConnections);
  496.  
  497.    if(objectCount > maxConnections)
  498.         {
  499.         printf("\nInsufficient connection slots to run this program!\n");
  500.         printf("Add CONNECTIONS = 50 in the NET.CFG under the \n");
  501.         printf("NetWare DOS Requester    header!\n");
  502.         return(err);
  503.         }
  504.  
  505.     for (i = 0; i < objectCount; i++)
  506.         {
  507.         dscCode = NWDSGetObjectName(
  508.                     /* Req. Context     */ dContext,
  509.                     /* P. to result buf */ buffer,
  510.                     /* object name      */ objectName,
  511.                     /* Attribute count  */ &attrCount,
  512.                     /* object Info      */ &objectInfo
  513.                     );
  514.  
  515.         if (dscCode < 0)
  516.             {
  517.             printf("\nNWDSGetObjectName returned: %04X\n", dscCode);
  518.             return(dscCode);
  519.             }
  520.  
  521.  
  522.         ReadPartInfo(objectName);
  523.  
  524.         } /* end of objects loop */
  525.     return(0);
  526. }
  527.  
  528.  
  529.  
  530. ReadPartInfo(char        *serverName)
  531. {
  532.     NWDSCCODE            dscCode;
  533.    NWDS_ITERATION    iterHandle = (NWDS_ITERATION)-1;
  534.    NWDS_BUFFER NWFAR *retBuf = NULL;
  535.     NWCOUNT                partCount;
  536.     char                    partName[256];
  537.     char                    tempName[256];
  538.     NWREPLICA_TYPE        replicaType;
  539.  
  540.     struct    PartRecord    *ptrthis=NULL, *ptrnew=NULL, *ptrfirst=NULL;
  541.     int                    i;
  542.  
  543.  
  544.     /*----------------------------------------------------------------
  545.     ** Allocate a buffer to receive the results.
  546.     */
  547.     dscCode = NWDSAllocBuf(
  548.                 /* Buffer Size */ DEFAULT_MESSAGE_LEN,
  549.                 /* Buff. Point.*/ &retBuf
  550.                 );
  551.  
  552.     if (dscCode < 0)
  553.             {
  554.             printf("NWDSAllocBuf returned: %04X\n", dscCode);
  555.             goto Out;
  556.             }
  557.  
  558.  
  559.  
  560.     pnew = (struct ServerRecord    *) malloc( sizeof(struct ServerRecord));
  561.     if(pfirst == (struct ServerRecord *)NULL)
  562.        pfirst = pthis = pnew;
  563.  
  564.     else
  565.        {
  566.          pthis = pfirst;
  567.          while ( pthis->pnext != (struct ServerRecord *)NULL)
  568.                 pthis = pthis->pnext;
  569.          pthis->pnext=pnew;
  570.          pthis = pnew;
  571.         }
  572.     strcpy(pthis->serverName, serverName);
  573.     pthis->pnext = (struct ServerRecord *) NULL;
  574.  
  575.    do
  576.    {
  577.     dscCode = NWDSListPartitions(
  578.                     /* Context handle */ dContext,
  579.                     /* Interation hndl*/ &iterHandle,
  580.                     /* Server Name    */ serverName,
  581.                     /* Result Buffer  */ retBuf
  582.                     );
  583.  
  584.     if (dscCode < 0)
  585.             {
  586.             printf("NWDSListPartitions returned: %04X\n", dscCode);
  587.             goto Out;
  588.             }
  589.  
  590.  
  591.    }
  592.    while (iterHandle != (NWDS_ITERATION)-1);
  593.  
  594.  
  595.  
  596.     dscCode = NWDSGetServerName(
  597.                      /* Context hndl */ dContext,
  598.                     /* result Buffer*/ retBuf,
  599.                     /* OUT server DN*/ tempName,
  600.                     /* part. Count  */ &partCount
  601.                     );
  602.  
  603.     if (dscCode < 0)
  604.             {
  605.             printf("NWDSGetServerName returned: %04X\n", dscCode);
  606.             goto Out;
  607.             }
  608.  
  609.     for(i=0; i < partCount; ++i)
  610.         {
  611.  
  612.         dscCode = NWDSGetPartitionInfo(
  613.                         /* Context Handle */ dContext,
  614.                         /* Result buffer  */ retBuf,
  615.                         /* partition name */ partName,
  616.                         /* replica Type   */ &replicaType
  617.                         );
  618.     
  619.         if (dscCode < 0)
  620.                 {
  621.                   printf("NWDSGetPartitionInfo returned: %04X\n", dscCode);
  622.                 goto Out;
  623.                 }
  624.  
  625.         
  626.         ptrnew = (struct PartRecord    *) malloc( sizeof(struct PartRecord));
  627.         if(ptrfirst == (struct PartRecord *)NULL)
  628.            ptrfirst = ptrthis = ptrnew;
  629.  
  630.         else
  631.             {
  632.              ptrthis = ptrfirst;
  633.              while ( ptrthis->pnext != (struct PartRecord *)NULL)
  634.                     ptrthis = ptrthis->pnext;
  635.              ptrthis->pnext=ptrnew;
  636.              ptrthis = ptrnew;
  637.          }
  638.  
  639.         strcpy(ptrthis->partRoot, partName);
  640.         ptrthis->replicaType = replicaType;
  641.         ptrthis->connectFail = 0;
  642.         ptrthis->pnext = (struct PartRecord *) NULL;
  643.  
  644.         ReadSyncTimes(tempName, partName, ptrthis);
  645.  
  646.          }
  647.         pthis->headlst = ptrfirst;
  648.         
  649. Out:
  650.    if (retBuf)
  651.       NWDSFreeBuf(retBuf);
  652.  
  653.     return(0);
  654. }
  655.  
  656. ReadSyncTimes(char *serverName, char *partName, struct PartRecord *ptrthis)
  657. {
  658.     NWCCODE             cCode, cCode2;
  659.     NWDSCCODE        dscCode;
  660.     NWCONN_HANDLE    connHandle;
  661.     NWCONN_HANDLE  oldConnHandle;
  662.     char                shortServerName[256];
  663.     char                *ptr;
  664.     NWDS_BUFFER        *outBuf, *inBuf;
  665.     NWDS_ITERATION    iterHandle = -1L;
  666.     NWSYNTAX_ID        syntax;
  667.     NWSIZE            attrValSize;
  668.     NWCOUNT            attrCount;
  669.     NWCOUNT            valCount;
  670.     char                attrName[MAX_DN_CHARS + 1];
  671.     void                *attrVal;
  672.     int                h, i, j, k, cnt;
  673.  
  674.     char *attrList[] =
  675.     {
  676.     "Synchronized Up To"
  677.     };
  678.  
  679.     if (ptrthis->replicaType > 2)
  680.         {
  681.         strcpy(shortServerName, serverName);
  682.         ptr = strchr(shortServerName, '.');
  683.         if (ptr)
  684.             shortServerName[ptr-shortServerName] = '\0';
  685.     
  686.         cCode = NWGetDefaultConnectionID(
  687.                         /* connection handle */ &oldConnHandle
  688.                         );
  689.  
  690.         cCode = NWGetConnectionHandle(
  691.                     /* Server Name     */ shortServerName,
  692.                     /* reserved        */ 0,
  693.                     /* Connection hand */ &connHandle,
  694.                     /* reserved        */ NULL
  695.                     );
  696.  
  697.         if ( cCode == INVALID_CONNECTION    )
  698.             {
  699.             cCode2 = NWAttachToFileServer(
  700.                         /* Server Name     */ shortServerName,
  701.                         /* scope           */ 0,
  702.                         /* new conn handle */ &connHandle
  703.                         );
  704.  
  705.  
  706.             if (cCode2)
  707.                     {
  708.                     printf("NWAttachToFileServer returned: %04X\n", cCode2);
  709.                     ptrthis->connectFail = 1;
  710.                     goto cleanUp;
  711.                     }
  712.  
  713.             }
  714.  
  715.         /*-------------------------------------------------------------------
  716.         **    The followin NWDSSetContext() is used to ensure that the read call
  717.         ** is issued to the server that actually contains the replica.
  718.         */
  719.  
  720.         dscCode = NWDSSetContext(
  721.                         /* context handle */ dContext,
  722.                         /* Key (command)  */ DCK_LAST_CONNECTION,
  723.                         /* connection hand*/ &connHandle
  724.                         );
  725.  
  726.  
  727.  
  728.         if (dscCode < 0)
  729.                 {
  730.                 printf("NWDSSetContext returned: %04X\n", dscCode);
  731.                 goto cleanUp;
  732.                 }
  733.         }
  734.     /*-------------------------------------------------------------------
  735.     **    Read the object info.
  736.     */
  737.  
  738.     dscCode = NWDSAllocBuf(
  739.                 /* Buffer Size */ DEFAULT_MESSAGE_LEN,
  740.                 /* Buff. Point.*/ &inBuf
  741.                 );
  742.  
  743.     if (dscCode < 0)
  744.             {
  745.             printf("NWDSAllocBuf returned: %04X\n", dscCode);
  746.             return(1);
  747.             }
  748.  
  749.    dscCode = NWDSInitBuf(
  750.                 /* Context  */ dContext,
  751.                 /* Operation*/ DSV_READ,
  752.                 /* buffer   */ inBuf
  753.                 );
  754.  
  755.  
  756.     if (dscCode < 0)
  757.             {
  758.             printf("NWDSInitBuf returned: %04X\n", dscCode);
  759.             NWDSFreeBuf(inBuf);
  760.             return(1);
  761.             }
  762.  
  763.     dscCode = NWDSAllocBuf(
  764.                 /* Buffer Size */ DEFAULT_MESSAGE_LEN,
  765.                 /* Buff. Point.*/ &outBuf
  766.                 );
  767.  
  768.     if (dscCode < 0)
  769.             {
  770.             printf("NWDSAllocBuf returned: %04X\n", dscCode);
  771.             NWDSFreeBuf(inBuf);
  772.             return(1);
  773.             }
  774.  
  775.     for(h = 0; h < 1; ++h)
  776.         {
  777.         dscCode = NWDSPutAttrName(
  778.                     /* context   */ dContext,
  779.                     /* in buffer */ inBuf,
  780.                     /* attr. name*/ (char NWFAR*)attrList[h]
  781.                     );
  782.  
  783.         if (dscCode < 0)
  784.                 {
  785.                 printf("NWDSPutAttrName returned: %04X\n", dscCode);
  786.                 NWDSFreeBuf(inBuf);
  787.                 NWDSFreeBuf(outBuf);
  788.                 return(1);
  789.                 }
  790.  
  791.         }
  792.  
  793.  
  794.    do
  795.    {
  796.     dscCode = NWDSRead(
  797.                 /* Context     */ dContext,
  798.                 /* Object name    */ partName,
  799.                 /* Info. Type  */ DS_ATTRIBUTE_VALUES,
  800.                 /* All Attrib ?*/ FALSE,
  801.                 /* Attri. names*/ inBuf,
  802.                 /* Iter. Handle*/ &iterHandle,
  803.                 /* Object info */ outBuf
  804.                 );
  805.  
  806.     if (dscCode < 0)
  807.         {
  808.         printf("\nNWDSRead returned: %04X\n", dscCode);
  809.         NWDSFreeBuf(inBuf);
  810.         NWDSFreeBuf(outBuf);
  811.         return(1);
  812.         }
  813.    }
  814.    while (iterHandle != (NWDS_ITERATION)-1);
  815.  
  816.  
  817.     /*----------------------------------------------------------------
  818.     **    Read Received Up to value
  819.     */
  820.  
  821.     dscCode = NWDSGetAttrCount(
  822.                 /* Context    */ dContext,
  823.                 /* attr. buff */ outBuf,
  824.                 /* num of attr*/ &attrCount
  825.                 );
  826.  
  827.     if (dscCode < 0)
  828.         {
  829.         printf("\nNWDSGetAttrCount returned: %04X\n", dscCode);
  830.         return(1);
  831.         }
  832.  
  833.     for (i = 0; i < attrCount; i++)
  834.         {
  835.         dscCode = NWDSGetAttrName(
  836.                     /* Context        */ dContext,
  837.                     /* attrib. buf    */ outBuf,
  838.                     /* attrib name    */ attrName,
  839.                     /* attr. val. cnt    */ &valCount,
  840.                     /* Syntax ID      */ &syntax
  841.                     );
  842.  
  843.         if (dscCode < 0)
  844.             {
  845.             printf("\nNWDSGetAttrName returned: %04X\n", dscCode);
  846.             return(1);
  847.             }
  848.  
  849.  
  850.         /*--------------------------------------------------------------
  851.         ** Get Received up to value.
  852.         */
  853.         for (j = 0; j < valCount; j++)
  854.             {
  855.             dscCode = NWDSComputeAttrValSize(
  856.                             /* Context handle */ dContext,
  857.                             /* Result Buffer  */ outBuf,
  858.                             /* Syntax ID      */ syntax,
  859.                             /* Size of attrib.*/ &attrValSize
  860.                             );
  861.  
  862.             attrVal = (void NWFAR *)malloc(attrValSize);
  863.  
  864.             dscCode = NWDSGetAttrVal(
  865.                         /* Context  */ dContext,
  866.                         /* read buf */ outBuf,
  867.                         /* syntax id*/ syntax,
  868.                         /* attr. val*/ attrVal
  869.                         );
  870.  
  871.             if (dscCode < 0)
  872.                 {
  873.                 printf("\nNWDSGetAttrVal returned: %04X\n", dscCode);
  874.                 return(1);
  875.                 }
  876.  
  877.             if (j == 2)
  878.                 {
  879.                 memcpy(&ptrthis->synchronizedUpTo, attrVal, attrValSize);
  880.                 }
  881.             free(attrVal);
  882.  
  883.             }
  884.  
  885.         }
  886.  
  887.  
  888.  
  889.  
  890.  
  891. cleanUp:
  892.  
  893.     if (ptrthis->replicaType > 2)
  894.         {
  895.         dscCode = NWDSSetContext(
  896.                         /* context handle */ dContext,
  897.                         /* Key (command)  */ DCK_LAST_CONNECTION,
  898.                         /* connection hand*/ &oldConnHandle
  899.                         );
  900.  
  901.  
  902.  
  903.         if (dscCode < 0)
  904.                 printf("NWDSSetContext returned: %04X\n", dscCode);
  905.  
  906.         }
  907.  
  908.     return(0);
  909. }
  910.  
  911.  
  912. DisplayRetrievedInfo(void)
  913. {
  914.     struct    tm        *reptm;
  915.     struct    PartRecord    *ptrthis=NULL;
  916.     char        replicaDescription[30];
  917.  
  918.     pthis = pfirst;
  919.  
  920.     putenv("TZ=MST7MDT");
  921.     tzset();
  922.  
  923.     do
  924.         {
  925.         printf("\nServer Name : %s", pthis->serverName);
  926.  
  927.         printf("\n\n\tPartitions : ");
  928.         ptrthis = (struct PartRecord *)pthis->headlst;
  929.         if (ptrthis == (struct PartRecord *)NULL)
  930.            {
  931.            printf("\nNone...");
  932.            }
  933.         while (ptrthis != (struct PartRecord *)NULL)
  934.             {
  935.             printf("\n\tPartition Name            : %s", ptrthis->partRoot);
  936.             GetReplicaDescription(ptrthis->replicaType, replicaDescription);
  937.  
  938.             printf("\n\tPartition Type            : %s", replicaDescription);
  939.             if (ptrthis->connectFail)
  940.                 {
  941.                 printf("\n\tUnable to connect to server %s .", pthis->serverName);
  942.                 printf("\n\tSynchronized Up To time stamp unverified for this server!");
  943.                 }
  944.             else
  945.                 {
  946.                 if(ptrthis->replicaType <= 2)
  947.                     {
  948.                     reptm = localtime(&ptrthis->synchronizedUpTo.wholeSeconds);
  949.                     printf("\n\tSynchronized Up To Time   : %s", asctime(reptm));
  950.                     }
  951.                 else
  952.                     {
  953.                     printf("\n\tSync Time N/A for this replica type\n");
  954.                     }
  955.                 }
  956.             ptrthis = ptrthis->pnext;
  957.             }
  958.  
  959.  
  960.         pthis = pthis->pnext;
  961.  
  962.         }
  963.     while ( pthis != (struct ServerRecord *)NULL);
  964.  
  965.     return(0);
  966. }
  967.  
  968.  
  969. GetReplicaDescription(NWREPLICA_TYPE replicaType, char *replicaDesc)
  970. {
  971.     switch(replicaType)
  972.         {
  973.  
  974.         case 0x00:
  975.                         strcpy(replicaDesc, "Master");
  976.                         break;
  977.  
  978.         case 0x01:
  979.                         strcpy(replicaDesc, "Read/Write");
  980.                         break;
  981.  
  982.         case 0x02:
  983.                         strcpy(replicaDesc, "Read Only");
  984.                         break;
  985.  
  986.         case 0x03:
  987.                         strcpy(replicaDesc, "Subordinate Reference");
  988.                         break;
  989.  
  990.         }
  991. }
  992.  
  993. FreeUpList(void)
  994. {
  995.  
  996.     struct    PartRecord    *ptrthis, *ptrfirst;
  997.  
  998.     while (pfirst != (struct ServerRecord *)NULL)
  999.     {
  1000.       pthis=pfirst->pnext;
  1001.       ptrfirst = (struct PartRecord *)pfirst->headlst;
  1002.       while (ptrfirst != (struct PartRecord *)NULL)
  1003.         {
  1004.         ptrthis = ptrfirst->pnext;
  1005.         free(ptrfirst);
  1006.         ptrfirst=ptrthis;
  1007.         }
  1008.       free(pfirst);
  1009.       pfirst=pthis;
  1010.     }
  1011.  
  1012.         return(0);
  1013. }
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.