home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xyzext.zip / xyz / server / xyzext.c < prev   
C/C++ Source or Header  |  1992-07-20  |  19KB  |  882 lines

  1.  
  2. #ifndef XYZEXT
  3. /*
  4.  * It doesn't make sense to not compile this file without -DXYZEXT;
  5.  * so let's always turn it on!
  6.  */
  7. #define XYZEXT
  8. #endif
  9.  
  10. /*
  11.  * NOTE: There is an issue as to what memory allocation routines to use.
  12.  * We would like to use the generic server routines Xalloc and Xfree but
  13.  * since we are probably very interested in using XYZ with these routines,
  14.  * we can't use them for XYZ's internal memory allocation - if we did
  15.  * double entry into the XYZ subsystem could result.  So we use the
  16.  * standard Unix malloc and free routines.  This might be a problem if
  17.  * the Unix memory allocation routines shouldn't be used.  An override
  18.  * is supplied by defining the XYZalloc and XYZfree macros to "use the
  19.  * right allocator."
  20.  *
  21.  * NOTE: We also don't use ALLOCATE_LOCAL and DEALLOCATE_LOCAL since
  22.  * they might rely on X's memory allocation functions.  Instead we
  23.  * use XYZalloc and XYZfree.
  24.  */
  25. #ifndef XYZalloc
  26. #define XYZalloc(size) malloc(size)
  27. #endif
  28. #ifndef XYZfree
  29. #define XYZfree(ptr) free(ptr)
  30. #endif
  31.  
  32. #include <string.h>
  33.  
  34. #include "X.h"
  35. #include "Xproto.h"
  36. #include "misc.h"
  37. #include "os.h"
  38. #include "dixstruct.h"
  39. #include "extnsionst.h"
  40.  
  41. #define XK_LATIN1
  42. #include <X11/keysymdef.h>
  43.  
  44. #define _XAMINE_YOUR_ZERVER_SERVER_
  45. #include "xyzstr.h"
  46. #include "xyz.h"
  47.  
  48. #define XYZ_NUM_BUCKETS 300
  49.  
  50. #define TAGNAME_IS_STATIC 0
  51. #define SHOULD_FREE_TAGNAME 1
  52.  
  53. typedef struct _TagRec TagRec, *Tag;
  54. struct _TagRec {
  55.    char *tagname;
  56.    int allocated_tagname;
  57.    unsigned char tracelevel;
  58.    int value;
  59.    Tag next;
  60.    struct XYZ_marker *marker;
  61. };
  62.  
  63. static Bool xyz_instrument = FALSE;
  64. static Bool xyz_trace = FALSE; 
  65. static int xyz_status = XYZ_NO_ERROR;
  66. static int current_tracelevel = XYZ_DEFAULT_TRACE_LEVEL;
  67. static Tag tag_hash_table[XYZ_NUM_BUCKETS];
  68.  
  69. static
  70. invalidate_markers(marker)
  71. struct XYZ_marker *marker;
  72. {
  73.    while(marker != NULL) {
  74.       marker->tag = NULL;
  75.       marker = marker->next;
  76.    }
  77. }
  78.  
  79. static unsigned int
  80. hash_function(string)
  81. char *string;
  82. {
  83.    unsigned int value;
  84.  
  85.    value = 0;
  86.    while(*string != '\0') {
  87.       value <<= 1;
  88.       value += *string;
  89.       string++;
  90.    }
  91.    return value % XYZ_NUM_BUCKETS;
  92. }
  93.  
  94. static Tag
  95. tag_find_or_add(tagname, if_should_free_tagname)
  96. char *tagname;
  97. int if_should_free_tagname;
  98. {
  99.    Tag tag;
  100.    unsigned int hash_num;
  101.  
  102.    hash_num = hash_function(tagname);
  103.    tag = tag_hash_table[hash_num];
  104.    while(tag != NULL) {
  105.       if(!strcmp(tagname, tag->tagname)) {
  106.      if(if_should_free_tagname == SHOULD_FREE_TAGNAME) {
  107.         XYZfree(tagname);
  108.      }
  109.      /* in table; return tag */
  110.      return tag;
  111.       }
  112.       /* keep looking though bucket list */
  113.       tag = tag->next;
  114.    }
  115.    /* tagname not in table; put in table */
  116.    tag = (Tag) XYZalloc(sizeof(TagRec));
  117.    if(tag == NULL) {
  118.       /* memory allocation failure; stop doing XYZ */
  119.       xyz_status = XYZ_ERROR;
  120.       if(if_should_free_tagname == SHOULD_FREE_TAGNAME) {
  121.      XYZfree(tagname);
  122.       }
  123.       return NULL;
  124.    }
  125.    tag->tagname = tagname;
  126.    /* we don't free in this case; we just remember if we should for later */
  127.    tag->allocated_tagname = if_should_free_tagname;
  128.    tag->value = 0;
  129.    tag->tracelevel = XYZ_DEFAULT_TRACE_LEVEL;
  130.    tag->next = tag_hash_table[hash_num];
  131.    tag->marker = NULL;
  132.    tag_hash_table[hash_num] = tag;
  133.    /* return newly created tag */
  134.    return tag;
  135. }
  136.  
  137. static Tag
  138. tag_find(tagname)
  139. char *tagname;
  140. {
  141.    Tag tag;
  142.    unsigned int hash_num;
  143.  
  144.    hash_num = hash_function(tagname);
  145.    tag = tag_hash_table[hash_num];
  146.    while(tag != NULL) {
  147.       if(!strcmp(tagname, tag->tagname)) {
  148.      /* in table; return tag */
  149.      return tag;
  150.       }
  151.       /* keep looking though bucket list */
  152.       tag = tag->next;
  153.    }
  154.    return NULL;
  155. }
  156.  
  157. static void
  158. tag_hash_table_init()
  159. {
  160.    int i;
  161.  
  162.    for(i=0;i<XYZ_NUM_BUCKETS;i++) {
  163.       tag_hash_table[i] = NULL;
  164.    }
  165. }
  166.  
  167. #ifdef UNUSED_CODE
  168.  
  169. static void
  170. tag_hash_table_flush()
  171. {
  172.    int i;
  173.    Tag tag;
  174.    Tag next;
  175.  
  176.    for(i=0;i<XYZ_NUM_BUCKETS;i++) {
  177.       tag = tag_hash_table[i];
  178.       while(tag != NULL) {
  179.          next = tag->next;
  180.      invalidate_markers(tag->marker);
  181.      if(tag->allocated_tagname) {
  182.         XYZfree(tag->tagname);
  183.      }
  184.      XYZfree(tag);
  185.      tag = next;
  186.       }
  187.       tag_hash_table[i] = NULL;
  188.    }
  189. }
  190.  
  191. #endif /* UNUSED_CODE */
  192.  
  193. static void
  194. reset_values()
  195. {
  196.    Tag tag;
  197.    Tag next;
  198.    Tag *tag_ptr;
  199.    int i;
  200.  
  201.    for(i=0;i<XYZ_NUM_BUCKETS;i++) {
  202.       tag_ptr = &tag_hash_table[i];
  203.       tag = tag_hash_table[i];
  204.       while(tag != NULL) {
  205.      next = tag->next;
  206.      if(tag->tracelevel == XYZ_DEFAULT_TRACE_LEVEL) {
  207.         *tag_ptr = tag->next;
  208.         invalidate_markers(tag->marker);
  209.         if(tag->allocated_tagname == SHOULD_FREE_TAGNAME) {
  210.                XYZfree(tag->tagname);
  211.         }
  212.         XYZfree(tag);
  213.      } else {
  214.         tag->value = 0;
  215.         tag_ptr = &tag->next;
  216.          }
  217.      tag = next;
  218.       }
  219.    }
  220. }
  221.  
  222. static void
  223. reset_trace_levels()
  224. {
  225.    Tag tag;
  226.    Tag next;
  227.    Tag *tag_ptr;
  228.    int i;
  229.  
  230.    for(i=0;i<XYZ_NUM_BUCKETS;i++) {
  231.       tag_ptr = &tag_hash_table[i];
  232.       tag = tag_hash_table[i];
  233.       while(tag != NULL) {
  234.      next = tag->next;
  235.      if(tag->value == 0) {
  236.         *tag_ptr = tag->next;
  237.         invalidate_markers(tag->marker);
  238.         if(tag->allocated_tagname == SHOULD_FREE_TAGNAME) {
  239.            XYZfree(tag->tagname);
  240.         }
  241.         XYZfree(tag);
  242.      } else {
  243.         tag->tracelevel = 0;
  244.         tag_ptr = &tag->next;
  245.          }
  246.      tag = next;
  247.       }
  248.    }
  249. }
  250.  
  251. static int
  252. ProcXYZ_Instrument(client)
  253. ClientPtr client;
  254. {
  255.    REQUEST(xXYZ_InstrumentReq);
  256.  
  257.    REQUEST_SIZE_MATCH(xXYZ_InstrumentReq);
  258.    xyz_instrument = stuff->instrument;
  259.    return client->noClientException;
  260. }
  261.  
  262. static int
  263. ProcXYZ_Trace(client)
  264. ClientPtr client;
  265. {
  266.    REQUEST(xXYZ_TraceReq);
  267.  
  268.    REQUEST_SIZE_MATCH(xXYZ_TraceReq);
  269.    xyz_trace = stuff->trace;
  270.    return client->noClientException;
  271. }
  272.  
  273. static int
  274. ProcXYZ_SetCurTraceLevel(client)
  275. ClientPtr client;
  276. {
  277.    REQUEST(xXYZ_SetCurTraceLevelReq);
  278.  
  279.    REQUEST_SIZE_MATCH(xXYZ_SetCurTraceLevelReq);
  280.    current_tracelevel = stuff->tracelevel;
  281.    return client->noClientException;
  282. }
  283.  
  284. static int
  285. ProcXYZ_QueryState(client)
  286. ClientPtr client;
  287. {
  288.    REQUEST(xXYZ_QueryStateReq);
  289.    xXYZ_QueryStateReply rep;
  290.    int n;
  291.  
  292.    REQUEST_SIZE_MATCH(xXYZ_QueryStateReq);
  293.    rep.type = X_Reply;
  294.    rep.length = 0;
  295.    rep.sequenceNumber = client->sequence;
  296.    rep.instrument = xyz_instrument;
  297.    rep.trace = xyz_trace;
  298.    rep.tracelevel = current_tracelevel;
  299.    rep.status = xyz_status;
  300.    if(client->swapped) {
  301.       swaps(&rep.sequenceNumber, n);
  302.       swapl(&rep.length, n);
  303.    }
  304.    WriteToClient(client, sizeof(xXYZ_QueryStateReply), 
  305.       (char *) &rep);
  306.    return client->noClientException;
  307. }
  308.  
  309. static int
  310. ProcXYZ_GetTag(client)
  311. ClientPtr client;
  312. {
  313.    REQUEST(xXYZ_GetTagReq);
  314.    xXYZ_GetTagReply rep;
  315.    Tag tag;
  316.    char *tagname;
  317.    int n;
  318.  
  319.    REQUEST_FIXED_SIZE(xXYZ_GetTagReq, stuff->nChars);
  320.    tagname = (char *) XYZalloc(sizeof(char) * stuff->nChars + 1);
  321.    if(!tagname) {
  322.       return BadAlloc;
  323.    }
  324.    strncpy(tagname, (char *) &stuff[1], stuff->nChars);
  325.    tagname[stuff->nChars] = '\0';
  326.    tag = tag_find(tagname);
  327.  
  328.    rep.type = X_Reply;
  329.    rep.length = 0;
  330.    rep.sequenceNumber = client->sequence;
  331.    if(tag != NULL) {
  332.       rep.tracelevel = tag->tracelevel;
  333.       rep.value = tag->value;
  334.    } else {
  335.       rep.tracelevel = XYZ_DEFAULT_TRACE_LEVEL;
  336.       rep.value = 0;
  337.    }
  338.    if(client->swapped) {
  339.       swaps(&rep.sequenceNumber, n);
  340.       swapl(&rep.length, n);
  341.       swapl(&rep.value, n);
  342.    }
  343.    WriteToClient(client, sizeof(xXYZ_GetTagReply), (char *) &rep);
  344.    XYZfree(tagname);
  345.    return client->noClientException;
  346. }
  347.  
  348. static int
  349. ProcXYZ_SetValue(client)
  350. ClientPtr client;
  351. {
  352.    REQUEST(xXYZ_SetValueReq);
  353.    Tag tag;
  354.    char *tagname;
  355.  
  356.    REQUEST_FIXED_SIZE(xXYZ_SetValueReq, stuff->nChars);
  357.    tagname = (char *) XYZalloc(sizeof(char) * stuff->nChars + 1);
  358.    if(!tagname) {
  359.       return BadAlloc;
  360.    }
  361.    /*
  362.     * the tagname we just allocate will be freed by the
  363.     * hash table management code; this is not a leak.
  364.     */
  365.    strncpy(tagname, (char *) &stuff[1], stuff->nChars);
  366.    tagname[stuff->nChars] = '\0';
  367.    tag = tag_find_or_add(tagname, SHOULD_FREE_TAGNAME);
  368.    if(tag != NULL) {
  369.       tag->value = stuff->value;
  370.    } else {
  371.       return BadAlloc;
  372.    }
  373.    return client->noClientException;
  374. }
  375.  
  376. static int
  377. ProcXYZ_SetTraceLevel(client)
  378. ClientPtr client;
  379. {
  380.    REQUEST(xXYZ_SetTraceLevelReq);
  381.    Tag tag;
  382.    char *tagname;
  383.  
  384.    REQUEST_FIXED_SIZE(xXYZ_SetTraceLevelReq, stuff->nChars);
  385.    tagname = (char *) XYZalloc(sizeof(char) * stuff->nChars + 1);
  386.    if(!tagname) {
  387.       return BadAlloc;
  388.    }
  389.    /*
  390.     * the tagname we just allocate will be freed by the
  391.     * hash table management code; this is not a leak.
  392.     */
  393.    strncpy(tagname, (char *) &stuff[1], stuff->nChars);
  394.    tagname[stuff->nChars] = '\0';
  395.    tag = tag_find_or_add(tagname, SHOULD_FREE_TAGNAME);
  396.    if(tag != NULL) {
  397.       tag->tracelevel = stuff->tracelevel;
  398.    } else {
  399.       return BadAlloc;
  400.    }
  401.    return client->noClientException;
  402. }
  403.  
  404. static Bool
  405. TagNameMatch(pattern, tagname)
  406. char *pattern;
  407. char *tagname;
  408. {
  409.    while(*pattern != '\0') {
  410.       if(*pattern == XK_asterisk) {
  411.      pattern++;
  412.      if(*pattern == '\0') {
  413.         return TRUE;
  414.      }
  415.      while(!TagNameMatch(pattern, tagname)) {
  416.         if(*tagname++ == '\0') {
  417.            return FALSE;
  418.         }
  419.      }
  420.      return TRUE;
  421.       } else {
  422.      if(*tagname == '\0') {
  423.         return FALSE;
  424.      } else {
  425.         if((*pattern != XK_question) && (*pattern != *tagname)) {
  426.            return FALSE;
  427.         }
  428.      }
  429.       }
  430.       pattern++;
  431.       tagname++;
  432.    }
  433.    return *tagname == '\0';
  434. }
  435.  
  436. static Bool
  437. TagNameMatchPatterns(patterns, numpats, tagname)
  438. char **patterns;
  439. int numpats;
  440. char *tagname;
  441. {
  442.    int i;
  443.  
  444.    for(i=0;i<numpats;i++) {
  445.       if(TagNameMatch(patterns[i], tagname)) {
  446.      return TRUE;
  447.       }
  448.    }
  449.    return FALSE;
  450. }
  451.  
  452. static int
  453. ProcXYZ_ListValues(client)
  454. ClientPtr client;
  455. {
  456.    REQUEST(xXYZ_ListValuesReq);
  457.    xXYZ_ListValuesReply rep;
  458.    Tag tag;
  459.    int npats;
  460.    char **patterns;
  461.    char *pattern;
  462.    int patlen;
  463.    char **tagnames;
  464.    int *values;
  465.    unsigned int maxtags;
  466.    int count;
  467.    int rc;
  468.    int i;
  469.    char *buffer;
  470.    char *bufptr;
  471.    int total_length;
  472.    int length;
  473.    int n;
  474.  
  475.    REQUEST_AT_LEAST_SIZE(xXYZ_ListValuesReq);
  476.    maxtags = stuff->maxtags;
  477.    npats = stuff->npats;
  478.    patterns = (char **) XYZalloc(sizeof(char*) * npats);
  479.    if(!patterns) {
  480.       return BadAlloc;
  481.    }
  482.    /* 
  483.     * buffer serves double duty for extracting patterns and
  484.     * building reply.
  485.     */
  486.    buffer = (char *) &stuff[1];
  487.    for(i=0; i<npats; i++) {
  488.       /* notice that each pattern starts at an aligned 4-byte boundary */
  489.       patlen = *((unsigned short *) buffer);
  490.       if(client->swapped) {
  491.      /* gross and ugly that we do this here! */
  492.      swaps(&patlen, n);
  493.       }
  494.       pattern = (char *) XYZalloc(sizeof(char) * patlen + 1);
  495.       if(pattern == NULL) {
  496.      /* deallocate all the patterns we have allocated so far */
  497.      for(n=0; n<i; n++) {
  498.        XYZfree(patterns[n]);
  499.      }
  500.      XYZfree(patterns);
  501.      return BadAlloc;
  502.       }
  503.       /* +2 advances past patlen field */
  504.       strncpy(pattern, buffer + 2, patlen);
  505.       pattern[patlen] = '\0';
  506.       patterns[i] = pattern;
  507.       buffer += patlen;
  508.       buffer = (char *) ((2 + (int)buffer + 3) & ~3);
  509.    }
  510.  
  511.    rep.type = X_Reply;
  512.    rep.sequenceNumber = client->sequence;
  513.  
  514.    values = (int *) XYZalloc(sizeof(int) * maxtags);
  515.    tagnames = (char **) XYZalloc(sizeof(char*) * maxtags);
  516.    if((!values) || (!tagnames)) {
  517.       if(values) XYZfree(values);
  518.       if(tagnames) XYZfree(tagnames);
  519.       return BadAlloc;
  520.    }
  521.    count = 0;
  522.    total_length = 0;
  523.    for(i=0;i<XYZ_NUM_BUCKETS;i++) {
  524.       tag = tag_hash_table[i];
  525.       while(tag != NULL) {
  526.      if(tag->value != 0) {
  527.         rc = TagNameMatchPatterns(patterns, npats, tag->tagname);
  528.         if(rc == 1) {
  529.                /* matches */
  530.            if(count < maxtags) {
  531.               tagnames[count] = tag->tagname;
  532.               values[count] = tag->value;
  533.               total_length += (4 + 2 + strlen(tag->tagname) + 3) >> 2;
  534.            }
  535.                count++;
  536.         }
  537.      }
  538.      tag = tag->next;
  539.       }
  540.    }
  541.    rep.length = total_length;
  542.    rep.returned = min(maxtags, count);
  543.    rep.total = count;
  544.    if(total_length > 0) {
  545.       buffer = (char *) XYZalloc(total_length << 2);
  546.       if(!buffer) {
  547.          for(i=0;i<npats;i++) {
  548.             XYZfree(patterns[i]);
  549.          }
  550.      XYZfree(patterns);
  551.          XYZfree(values);
  552.          XYZfree(tagnames);
  553.          return BadAlloc;
  554.       }
  555.       bufptr = buffer;
  556.       for(i=0;i<rep.returned;i++) {
  557.          length = strlen(tagnames[i]);
  558.          *((unsigned short *)bufptr) = length;
  559.          if(client->swapped) {
  560.             swaps((unsigned short *)bufptr, n);
  561.          }
  562.          bufptr += sizeof(unsigned short);
  563.          bcopy(tagnames[i], bufptr, length);
  564.          bufptr += length;
  565.          bufptr = (char *) ((int) (bufptr + 3) & ~3);
  566.          *((int *) bufptr) = values[i];
  567.          if(client->swapped) {
  568.             swapl((int *)bufptr, n);
  569.          }
  570.          bufptr += sizeof(int);
  571.       }
  572.    }
  573.  
  574.    if(client->swapped) {
  575.       swaps(&rep.sequenceNumber, n);
  576.       swapl(&rep.length, n);
  577.       swaps(&rep.returned, n);
  578.       swaps(&rep.total, n);
  579.    }
  580.    WriteToClient(client, sizeof(xXYZ_ListValuesReply), &rep);
  581.    if(rep.length) {
  582.       WriteToClient(client, total_length << 2, buffer);
  583.       XYZfree(buffer);
  584.    }
  585.    for(i=0;i<npats;i++) {
  586.       XYZfree(patterns[i]);
  587.    }
  588.    XYZfree(patterns);
  589.    XYZfree(values);
  590.    XYZfree(tagnames);
  591.    return client->noClientException;
  592. }
  593.  
  594. static int
  595. ProcXYZ_ResetValues(client)
  596. ClientPtr client;
  597. {
  598.    REQUEST(xXYZ_ResetValuesReq);
  599.  
  600.    REQUEST_SIZE_MATCH(xXYZ_ResetValuesReq);
  601.    reset_values();
  602.    xyz_status = XYZ_NO_ERROR;
  603.    return client->noClientException;
  604. }
  605.  
  606. static int
  607. ProcXYZ_ResetTraceLevels(client)
  608. ClientPtr client;
  609. {
  610.    REQUEST(xXYZ_ResetTraceLevelsReq);
  611.  
  612.    REQUEST_SIZE_MATCH(xXYZ_ResetTraceLevelsReq);
  613.    reset_trace_levels();
  614.    xyz_status = XYZ_NO_ERROR;
  615.    return client->noClientException;
  616. }
  617.  
  618. static int
  619. ProcXYZ_Dispatch(client)
  620. ClientPtr client;
  621. {
  622.    REQUEST(xReq);
  623.    switch(stuff->data) {
  624.    case X_XYZ_Instrument:
  625.       return ProcXYZ_Instrument(client);
  626.    case X_XYZ_Trace:
  627.       return ProcXYZ_Trace(client);
  628.    case X_XYZ_SetCurTraceLevel:
  629.       return ProcXYZ_SetCurTraceLevel(client);
  630.    case X_XYZ_QueryState:
  631.       return ProcXYZ_QueryState(client);
  632.    case X_XYZ_GetTag:
  633.       return ProcXYZ_GetTag(client);
  634.    case X_XYZ_SetValue:
  635.       return ProcXYZ_SetValue(client);
  636.    case X_XYZ_SetTraceLevel:
  637.       return ProcXYZ_SetTraceLevel(client);
  638.    case X_XYZ_ListValues:
  639.       return ProcXYZ_ListValues(client);
  640.    case X_XYZ_ResetValues:
  641.       return ProcXYZ_ResetValues(client);
  642.    case X_XYZ_ResetTraceLevels:
  643.       return ProcXYZ_ResetTraceLevels(client);
  644.    default:
  645.       return BadRequest;
  646.    }
  647. }
  648.  
  649. static int
  650. SProcXYZ_Instrument(client)
  651. ClientPtr client;
  652. {
  653.    REQUEST(xXYZ_InstrumentReq);
  654.    int n;
  655.  
  656.    swaps(&stuff->length, n);
  657.    return ProcXYZ_Instrument(client);
  658. }
  659.  
  660. static int
  661. SProcXYZ_Trace(client)
  662. ClientPtr client;
  663. {
  664.    REQUEST(xXYZ_TraceReq);
  665.    int n;
  666.  
  667.    swaps(&stuff->length, n);
  668.    return ProcXYZ_Trace(client);
  669. }
  670.  
  671. static int
  672. SProcXYZ_SetCurTraceLevel(client)
  673. ClientPtr client;
  674. {
  675.    REQUEST(xXYZ_SetCurTraceLevelReq);
  676.    int n;
  677.  
  678.    swaps(&stuff->length, n);
  679.    return ProcXYZ_SetCurTraceLevel(client);
  680. }
  681.  
  682. static int
  683. SProcXYZ_QueryState(client)
  684. ClientPtr client;
  685. {
  686.    REQUEST(xXYZ_QueryStateReq);
  687.    int n;
  688.  
  689.    swaps(&stuff->length, n);
  690.    return ProcXYZ_QueryState(client);
  691. }
  692.  
  693. static int
  694. SProcXYZ_GetTag(client)
  695. ClientPtr client;
  696. {
  697.    REQUEST(xXYZ_GetTagReq);
  698.    int n;
  699.  
  700.    swaps(&stuff->length, n);
  701.    swaps(&stuff->nChars, n);
  702.    return ProcXYZ_GetTag(client);
  703. }
  704.  
  705. static int
  706. SProcXYZ_SetValue(client)
  707. ClientPtr client;
  708. {
  709.    REQUEST(xXYZ_SetValueReq);
  710.    int n;
  711.  
  712.    swaps(&stuff->length, n);
  713.    swaps(&stuff->nChars, n);
  714.    swapl(&stuff->value, n);
  715.    return ProcXYZ_SetValue(client);
  716. }
  717.  
  718. static int
  719. SProcXYZ_SetTraceLevel(client)
  720. ClientPtr client;
  721. {
  722.    REQUEST(xXYZ_SetTraceLevelReq);
  723.    int n;
  724.  
  725.    swaps(&stuff->length, n);
  726.    swaps(&stuff->nChars, n);
  727.    return ProcXYZ_SetTraceLevel(client);
  728. }
  729.  
  730. static int
  731. SProcXYZ_ListValues(client)
  732. ClientPtr client;
  733. {
  734.    REQUEST(xXYZ_ListValuesReq);
  735.    int n;
  736.  
  737.    swaps(&stuff->length, n);
  738.    swaps(&stuff->npats, n);
  739.    swaps(&stuff->maxtags, n);
  740.    return ProcXYZ_ListValues(client);
  741. }
  742.  
  743. static int
  744. SProcXYZ_ResetValues(client)
  745. ClientPtr client;
  746. {
  747.    REQUEST(xXYZ_ResetValuesReq);
  748.    int n;
  749.  
  750.    swaps(&stuff->length, n);
  751.    return ProcXYZ_ResetValues(client);
  752. }
  753.  
  754. static int
  755. SProcXYZ_ResetTraceLevels(client)
  756. ClientPtr client;
  757. {
  758.    REQUEST(xXYZ_ResetTraceLevelsReq);
  759.    int n;
  760.  
  761.    swaps(&stuff->length, n);
  762.    return ProcXYZ_ResetTraceLevels(client);
  763. }
  764.  
  765. static int
  766. SProcXYZ_Dispatch(client)
  767. ClientPtr client;
  768. {
  769.    REQUEST(xReq);
  770.    switch(stuff->data) {
  771.    case X_XYZ_Instrument:
  772.       return SProcXYZ_Instrument(client);
  773.    case X_XYZ_Trace:
  774.       return SProcXYZ_Trace(client);
  775.    case X_XYZ_SetCurTraceLevel:
  776.       return SProcXYZ_SetCurTraceLevel(client);
  777.    case X_XYZ_QueryState:
  778.       return SProcXYZ_QueryState(client);
  779.    case X_XYZ_GetTag:
  780.       return SProcXYZ_GetTag(client);
  781.    case X_XYZ_SetValue:
  782.       return SProcXYZ_SetValue(client);
  783.    case X_XYZ_SetTraceLevel:
  784.       return SProcXYZ_SetTraceLevel(client);
  785.    case X_XYZ_ListValues:
  786.       return SProcXYZ_ListValues(client);
  787.    case X_XYZ_ResetValues:
  788.       return SProcXYZ_ResetValues(client);
  789.    case X_XYZ_ResetTraceLevels:
  790.       return SProcXYZ_ResetTraceLevels(client);
  791.    default:
  792.       return BadRequest;
  793.    }
  794. }
  795.  
  796. static void
  797. XYZ_Reset(extEntry)
  798. ExtensionEntry *extEntry;
  799. {
  800. }
  801.  
  802. void
  803. XamineYourZerverInit(argc, argv)
  804. int argc;
  805. char *argv[];
  806. {
  807.    ExtensionEntry *extEntry;
  808.    int i;
  809.    static int beenhere = FALSE;
  810.  
  811.    extEntry = AddExtension(XAMINE_YOUR_ZERVER_NAME,
  812.       XYZ_NumberEvents, XYZ_NumberErrors,
  813.       ProcXYZ_Dispatch, SProcXYZ_Dispatch, 
  814.       XYZ_Reset, StandardMinorOpcode);
  815.  
  816.    if(!beenhere) {
  817.       beenhere = TRUE;
  818.       tag_hash_table_init();
  819.  
  820.       xyz_instrument = FALSE;
  821.       xyz_trace = FALSE;
  822.       xyz_status = XYZ_NO_ERROR;
  823.  
  824.       /* look for -xyz command line arg to start with XYZ on */
  825.       if(extEntry != NULL) {
  826.          for(i=1;i<argc;i++) {
  827.         if(!strcmp(argv[i], "-xyz")) {
  828.                xyz_instrument = TRUE;
  829.            return;
  830.         }
  831.         if(!strcmp(argv[i], "-xyztrace")) {
  832.            xyz_trace = TRUE;
  833.            return;
  834.         }
  835.         if(!strcmp(argv[i], "-xyzboth")) {
  836.            xyz_instrument = TRUE;
  837.            xyz_trace = TRUE;
  838.                return;
  839.            }
  840.          }
  841.       }
  842.    }
  843. }
  844.  
  845. void
  846. XamineYourZerver(tagname, delta, marker)
  847. char *tagname;
  848. int delta;
  849. struct XYZ_marker *marker;
  850. {
  851.    Tag tag;
  852.    int tracelevel;
  853.  
  854.    tag = (Tag) ((marker->tag != NULL) ? marker->tag : NULL);
  855.    if(xyz_instrument) {
  856.       if(xyz_status == XYZ_NO_ERROR) {
  857.      if(tag == NULL) {
  858.             tag = tag_find_or_add(tagname, TAGNAME_IS_STATIC); 
  859.         marker->tag = (void *) tag;
  860.         marker->next = tag->marker;
  861.         tag->marker = marker;
  862.      }
  863.          tag->value += delta;
  864.       }
  865.    }
  866.    if(xyz_trace) {
  867.       if(tag == NULL) {
  868.          tag = tag_find(tagname); 
  869.      if(tag != NULL) {
  870.         marker->tag = (void *) tag;
  871.         marker->next = tag->marker;
  872.         tag->marker = marker;
  873.      }
  874.       }
  875.       tracelevel = (tag != NULL) ? tag->tracelevel : XYZ_DEFAULT_TRACE_LEVEL;
  876.       if(tracelevel <= current_tracelevel) {
  877.          ErrorF("XYZ: %s = %d\n", tagname, tag == NULL ? 0 : tag->value);
  878.       }
  879.    }
  880. }
  881.  
  882.