home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / VP2_409E.SZH / AREASBBS.C < prev    next >
Text File  |  1991-07-13  |  22KB  |  720 lines

  1. /*
  2.   $Header: areasbbs.c 3.3 87/12/12 00:40:08 Bob Exp $
  3.  
  4.                           The Conference Mail System
  5.  
  6.               This module was originally written by Bob Hartman
  7.                        Sysop of FidoNet node 1:132/101
  8.  
  9.    Spark Software, 427-3 Amherst St, CS 2032, Suite 232, Nashua, NH 03061
  10.  
  11.  The Conference Mail System  is a  complete Echomail processing package.  It
  12.  is a superset of the original  Echomail utilities created by Jeff Rush, and
  13.  also contains ideas gleaned from the  ARCmail,  Renum,  oMMM, MGM, and Opus
  14.  programs that were created by various software authors.
  15.  
  16.  This program source code is being released with the following provisions:
  17.  
  18.  1.  You are  free to make  changes to this source  code for use on your own
  19.  machine,  however,  altered source files may not be distributed without the
  20.  consent of Spark Software.
  21.  
  22.  2.  You may distribute "patches"  or  "diff" files for any changes that you
  23.  have made, provided that the "patch" or "diff" files are also sent to Spark
  24.  Software for inclusion in future releases of the entire package.   A "diff"
  25.  file for the source archives may also contain a compiled version,  provided
  26.  it is  clearly marked as not  being created  from the original source code.
  27.  No other  executable  versions may be  distributed without  the  consent of
  28.  Spark Software.
  29.  
  30.  3.  You are free to include portions of this source code in any program you
  31.  develop, providing:  a) Credit is given to Spark Software for any code that
  32.  may is used, and  b) The resulting program is free to anyone wanting to use
  33.  it, including commercial and government users.
  34.  
  35.  4.  There is  NO  technical support  available for dealing with this source
  36.  code, or the accompanying executable files.  This source  code  is provided
  37.  as is, with no warranty expressed or implied (I hate legalease).   In other
  38.  words, if you don't know what to do with it,  don't use it,  and if you are
  39.  brave enough to use it, you're on your own.
  40.  
  41.  Spark Software may be contacted by modem at (603) 888-8179 (node 1:132/101)
  42.  on the public FidoNet network, or at the address given above.
  43.  
  44.  To use this code you will need Microsoft C version 4.0, and also Microsoft
  45.  Macro Assembler version 4.0.
  46.  
  47. */
  48.  
  49. /*
  50.    $Log:    areasbbs.c $
  51.  * Revision 4.09d 91/06/11            GJS
  52.  * Update for to include statistics and logging
  53.  *
  54.  * Revision 3.3  87/12/12  00:40:08  Bob
  55.  * Source code release
  56.  *
  57. */
  58.  
  59. #include <stdio.h>
  60. #include <ctype.h>
  61. #include <malloc.h>
  62. #include <string.h>
  63. #include <stdlib.h>
  64. #include <math.h>
  65. #include <process.h>
  66. #include "fastecho.h"
  67.  
  68. #define DEBUG 0
  69.  
  70. /* Remember to change the security check routine also! */
  71. #ifdef OS2
  72. char *NAME="\r\n--- VP[OS/2] V%s\r\n";
  73. #else  /* OS2 */
  74. char *NAME="\r\n--- VP [DOS] V%s\r\n";
  75. #endif /* OS2 */
  76.  
  77. extern SEACONFIG config;
  78. extern AREAS_PTR areas[];
  79. extern char board_name[], sysop_name[];
  80. extern int tot_areas;
  81. extern char bbsfile[];
  82. extern int seen_aka;
  83. char tmpjunk[256], tmpjunk1[80], tmpjunk2[80];
  84. extern char *areaserr;
  85. int priv_net = 0;
  86. int boss_net = 0;
  87. int boss_node = 0;
  88. int zone_zone[10];
  89. int zone_net[10];
  90. int zone_node[10];
  91. int num_zone = 0;
  92. int pass_thru = -1;
  93. int route_thru = -1;
  94. int bad_msgs = -1;
  95. int do_pickup = 0;
  96. int mail_dir = -1;
  97. char pickup_dir[64];
  98. extern PW_PTR pw[];
  99. extern int num_pw;
  100.  
  101. int compile_areas (char *fname)
  102. {
  103.     FILE *f;
  104.     char *p, *q, *r;
  105.     int i, k, last_net, err, intt1, intt2, last_zone;
  106.     int *tmpzone, *tmpnet, *tmpnode;
  107.     AREAS *aptr, *aptr1;
  108.     PW_PTR pptr;
  109.  
  110.     tmpzone = (int *) malloc (sizeof(int) * 100);
  111.     tmpnet = (int *) malloc (sizeof(int) * 100);
  112.     tmpnode = (int *) malloc (sizeof (int) * 100);
  113.  
  114.     if ((tmpnet == NULL) || (tmpnode == NULL) || (tmpzone == NULL))
  115.         {
  116.         printf (areaserr);
  117.         exit (2);
  118.         }
  119.  
  120.     strncpy (bbsfile, fname, 80);
  121.     if (bbsfile[0] == '\0')
  122.         strcpy (bbsfile, "AREAS.BBS");
  123.  
  124.     if ((f = fopen (bbsfile, "r")) == NULL)
  125.         {
  126. #if DEBUG
  127. printf ("Could not open AREAS file\n");
  128. #endif
  129.         free ((char *) tmpzone);
  130.         free ((char *) tmpnet);
  131.         free ((char *) tmpnode);
  132.         return (-1);
  133.         }
  134.  
  135. #if DEBUG
  136. printf ("Going into areasbbs loop\n");
  137. #endif
  138.     tot_areas = -1;
  139.     while (echo_fgets (tmpjunk, 256, f) != 0)
  140.         {
  141.         /* Was it a comment line? */
  142.         if (tmpjunk[0] == ';')
  143.             {
  144.             /* Yes it was, so continue */
  145.             continue;
  146.             }
  147. #if DEBUG
  148. printf ("Got '%s'\n", tmpjunk);
  149. #endif
  150.  
  151.       /* Was it a special FastEcho line? */
  152.       if (tmpjunk[0] == '-')
  153.          {
  154.          /* Yes it was, so do whatever it says */
  155.          if (strnicmp (tmpjunk, "-ZONEGATE=", 10) == 0)
  156.             {
  157.             /* It is a ZONEGATE statement */
  158.             q = &tmpjunk[10];
  159.             i = 0;
  160.             last_zone = config.net[1];
  161.             while (*q)
  162.                {
  163.                zone_net[num_zone] = atoi (q);
  164.                while (*q)
  165.                   {
  166.                   if (*q == '/')
  167.                      break;
  168.                   else
  169.                      ++q;
  170.                   }
  171.                if (*q == '/')
  172.                   {
  173.                   ++q;
  174.                   zone_node[num_zone] = atoi (q);
  175.                   last_zone = zone_net[num_zone];
  176.                   }
  177.                else
  178.                   {
  179.                   zone_node[num_zone] = zone_net[num_zone];
  180.                   zone_net[num_zone] = last_zone;
  181.                   }
  182.                ++num_zone;
  183.                while (*q)
  184.                   {
  185.                   if (isdigit(*q))
  186.                      ++q;
  187.                   else
  188.                      break;
  189.                   }
  190.                while (*q)
  191.                   {
  192.                   if (isspace(*q))
  193.                      ++q;
  194.                   else
  195.                      break;
  196.                   }
  197.                }
  198.             continue;
  199.             }
  200.          if (strnicmp (tmpjunk, "-PASSWORD=", 9) == 0)
  201.             {
  202.             /* It is a PASSWORD statement */
  203.             q = &tmpjunk[10];
  204.             intt1 = atoi (q);
  205.             while (*q)
  206.                {
  207.                if (!isdigit(*q))
  208.                   break;
  209.                else
  210.                   ++q;
  211.                }
  212.             if (*q == '/')
  213.                {
  214.                ++q;
  215.                intt2 = atoi (q);
  216.                }
  217.             else
  218.                {
  219.                intt2 = intt1;
  220.                intt1 = config.net[1];
  221.                }
  222.             while (*q)
  223.                {
  224.                if (isdigit(*q) || isspace(*q))
  225.                   ++q;
  226.                else
  227.                   break;
  228.                }
  229.             p = q;
  230.             while (*q)
  231.                {
  232.                if (isspace (*q))
  233.                   {
  234.                   *q = '\0';
  235.                   break;
  236.                   }
  237.                ++q;
  238.                }
  239.  
  240.             /* If we are here we have the proper net/node for the password
  241.                and we are pointing at the password itself, now just fill
  242.                in the proper fields and increment the counter */
  243.             pptr = pw[num_pw] = (PW_PTR) calloc (1, sizeof (PW));
  244.             if (pptr == NULL)
  245.                 {
  246.                 printf (areaserr);
  247.                 exit (2);
  248.                 }
  249.  
  250.             pptr->net = intt1;
  251.             pptr->node = intt2;
  252.             /* Length of password hoped for */
  253.             intt1 = strlen(p);
  254.             /* Max it out at 8 */
  255.             intt2 = (intt1>8)?8:intt1;
  256.             /* Allocate 9 bytes */
  257.             pptr->password = calloc (1, 9);
  258.             /* Copy in what we have */
  259.             strncpy (pptr->password, p, intt2);
  260.             for (intt1 = 0; intt1 < 8; intt1++)
  261.                pptr->password[intt1] = (char) toupper (pptr->password[intt1]);
  262.             ++num_pw;
  263.             continue;
  264.             }
  265. #if POINT_TYPE
  266.          else if (strnicmp (tmpjunk, "-PICKUPDIR=", 11) == 0)
  267.             {
  268.             q = &tmpjunk[11];
  269.             while (*q && !isspace (*q))
  270.                ++q;
  271.             *q = '\0';
  272.             strcpy (pickup_dir, &tmpjunk[11]);
  273.             do_pickup = 1;
  274.             continue;
  275.             }
  276.          else if (strnicmp (tmpjunk, "-POINTNET=", 10) == 0)
  277.             {
  278.             /* It is a POINTNET statement */
  279.             q = &tmpjunk[10];
  280.             priv_net = atoi (q);
  281. #if DEBUG
  282. printf ("Point network '%d' found\n", priv_net);
  283. #endif
  284.             continue;
  285.             }
  286.          else if (strnicmp (tmpjunk, "-BOSSNODE=", 10) == 0)
  287.             {
  288.             q = &tmpjunk[10];
  289.             boss_net = atoi (q);
  290.             while (*q)
  291.                {
  292.                if (*q == '/')
  293.                   break;
  294.                else
  295.                   ++q;
  296.                }
  297.             if (*q == '/')
  298.                {
  299.                ++q;
  300.                boss_node = atoi (q);
  301.                }
  302.             else
  303.                {
  304.                boss_node = boss_net;
  305.                boss_net = config.net[1];
  306.                }
  307.             continue;
  308.             }
  309. #endif
  310.          continue;
  311.          }
  312.  
  313.         p = tmpjunk;
  314.         q = tmpjunk1;
  315.  
  316.         /* Extract first word */
  317.         if (get_word (&p, q) == 0)
  318.             {
  319.             continue;
  320.             }
  321.  
  322.         /* Is this the header stuff? */
  323.         if (tot_areas == -1)
  324.             {
  325.             /* It is, so create the board name and sysop name */
  326.             q = (char *) (tmpjunk + strlen (tmpjunk) - 1);
  327.             while ((q >= tmpjunk) && (isspace (*q)))
  328.             *q-- = '\0';
  329.             if ((q = strrchr (tmpjunk, '!')) != NULL)
  330.                 {
  331.                 r = q-1;
  332.                 while (isspace (*r))
  333.                     {
  334.                     *r-- = '\0';
  335.                     }
  336.                 *q++ = '\0';
  337.                 while (isspace (*q))
  338.                     ++q;
  339.  
  340.                 strncpy (sysop_name, q, 126);
  341.                 strncpy (board_name, tmpjunk, 126);
  342.                 tot_areas = 0;
  343.                 continue;
  344.                 }
  345.             else
  346.                 {
  347.                 strncpy (board_name, tmpjunk, 126);
  348.                 tot_areas = 0;
  349.                 continue;
  350.                 }
  351.             }
  352.  
  353.         q = tmpjunk1;
  354.         if (q[strlen(q)-1] == '\\')
  355.             q[strlen(q)-1] = '\0';
  356.         while (*q)
  357.             {
  358.             *q = (char) toupper (*q);
  359.             ++q;
  360.             }
  361.         strcpy (tmpjunk2, tmpjunk1);
  362.  
  363.         /* Is it a legitimate directory? */
  364.         if (!(filedir (tmpjunk1, 0, tmpjunk1, ST_DIRECT) & ST_DIRECT))
  365.             {
  366.             strcpy (tmpjunk1,tmpjunk2);
  367.             /* Not a directory, continue on */
  368.             if (get_fido_sys (tmpjunk1, 1))
  369.                 {
  370.                 continue;
  371.                 }
  372.             }
  373.         else
  374.             strcpy (tmpjunk1, tmpjunk2);
  375.  
  376.         /* It is the message path directly */
  377.         aptr = areas[tot_areas] = (AREAS_PTR) calloc (1, sizeof (AREAS));
  378.         if (aptr == NULL)
  379.             {
  380.             printf (areaserr);
  381.             exit (2);
  382.             }
  383.         aptr->msg_path = malloc ((unsigned) (strlen(tmpjunk1)+1));
  384.         if (aptr->msg_path == NULL)
  385.             {
  386.             printf (areaserr);
  387.             exit (2);
  388.             }
  389.         strcpy (aptr->msg_path, tmpjunk1);
  390.         q = aptr->msg_path;
  391.         while (*q)
  392.             {
  393.             *q = (char) toupper(*q);
  394.             ++q;
  395.             }
  396.  
  397.         /* Now get the next word into the area name field */
  398.         q = tmpjunk1;
  399.         if (get_word (&p, q) == 0)
  400.             {
  401.             continue;
  402.             }
  403.  
  404.         while (*q)
  405.             {
  406.             *q = (char) toupper (*q);
  407.             ++q;
  408.             }
  409.  
  410.         aptr->area_name = malloc ((unsigned) (strlen (tmpjunk1)+1));
  411.         if (aptr->area_name == NULL)
  412.             {
  413.             printf (areaserr);
  414.             exit (2);
  415.             }
  416.         strcpy (aptr->area_name, tmpjunk1);
  417.  
  418.         #if STATS
  419.             /* set the stats/logging to zero as the starting point */
  420.             aptr->msgs_proc   = 0;
  421.             aptr->msgs_size   = 0;
  422.             aptr->msg_dupes   = 0;
  423.             aptr->msgs_sec    = 0;
  424.         #endif
  425.  
  426.         if (strcmp (tmpjunk1, "PASSTHRU") == 0)
  427.          {
  428.          aptr->flags |= PASS_THRU;
  429.          pass_thru = tot_areas;
  430.          }
  431.       else if (strcmp (tmpjunk1, "ROUTETHRU") == 0)
  432.          {
  433.          aptr->flags |= ROUTETHRU;
  434.          route_thru = tot_areas;
  435.          }
  436.       else if (strcmp (tmpjunk1, "BAD_MSGS") == 0)
  437.          {
  438.          aptr->flags |= BAD_MSGS;
  439.          bad_msgs = tot_areas;
  440.          }
  441.       else if (strcmp (tmpjunk1, "aMAIL_DIR") == 0)
  442.          {
  443.          aptr->flags |= MAIL_DIR;
  444.          mail_dir = tot_areas;
  445.          }
  446.  
  447. #ifdef VPURGE
  448. #if DEBUG
  449.         printf ("Checking for V_PURGE now.\n");
  450. #endif
  451.         if (strchr(tmpjunk, '#') != NULL)
  452.             {
  453. #if DEBUG
  454.             printf ("Setting V_PURGE now.\n");
  455. #endif
  456.             aptr->flags |= V_PURGE;
  457.             }
  458. #endif
  459.  
  460.         /* Finally, get all of the net/node pairs */
  461.         i = 0;
  462.         last_net = config.net[1];
  463.         while (get_word (&p, tmpjunk1) != 0)
  464.             {
  465.             if ((err = sscanf (tmpjunk1, "%d:%d/%d", &(tmpzone[i]), &(tmpnet[i]),
  466.             &(tmpnode[i]))) < 3)
  467.             {
  468.             if (err == 0)
  469.                continue;
  470.  
  471.             tmpzone[i] = config.zone[1];
  472.             if ((err = sscanf (tmpjunk1, "%d/%d", &(tmpnet[i]),
  473.                                &(tmpnode[i]))) < 2)
  474.                {
  475.                tmpnode[i] = tmpnet[i];
  476.                tmpnet[i] = last_net;
  477.                }
  478.             }
  479.  
  480. #if DEBUG
  481. printf ("Using %d:%d/%d for i=%d\n", tmpzone[i], tmpnet[i], tmpnode[i], i);
  482. #endif
  483.  
  484.             for (k = 0; k < i; k++)
  485.                 {
  486.                 if ((tmpnet[k] == tmpnet[i]) &&
  487.                      (tmpnode[k] == tmpnode[i]) &&
  488.                 (tmpzone[k] == tmpzone[i]))
  489.                     {
  490.                     break;
  491.                     }
  492.                 }
  493.             if (k >= i)
  494.                {
  495.                last_net = tmpnet[i];
  496.                ++i;
  497.                }
  498.             }
  499.         aptr->num_nodes = i;
  500.         aptr->zone = (int *) malloc ((unsigned) (sizeof(int) * (i + seen_aka)));
  501.         aptr->net = (int *) malloc ((unsigned) (sizeof(int) * (i + seen_aka)));
  502.         aptr->node = (int *) malloc ((unsigned) (sizeof (int) * (i + seen_aka)));
  503.         aptr->handle = (int *) malloc ((unsigned) (sizeof (int) * (i + seen_aka)));
  504.         aptr->aname = (char **) malloc ((unsigned) (sizeof (char *) * (i + seen_aka)));
  505.  
  506.         #if STATS
  507.             aptr->msgs_scanned = (int *) malloc ((unsigned) (sizeof (int) * (i + seen_aka)));
  508.         #endif
  509.  
  510.         if ((aptr->net == NULL) || (aptr->node == NULL) || (aptr->zone == NULL) ||
  511.           (aptr->handle == NULL) || (aptr->aname == NULL))
  512.            {
  513.            printf (areaserr);
  514.            exit (2);
  515.            }
  516.  
  517.         for(i = 0; i < aptr->num_nodes; i++)
  518.            {
  519.            aptr->zone[i] = tmpzone[i];
  520.            aptr->net[i] = tmpnet[i];
  521.            aptr->node[i] = tmpnode[i];
  522.  
  523.            #if STATS
  524.                aptr->msgs_scanned[i] = 0;
  525.            #endif
  526.  
  527.            }
  528.  
  529.       for (i = 0; i < aptr->num_nodes + seen_aka; i++)
  530.          {
  531.          aptr->handle[i] = -1;
  532.          aptr->aname[i] = aptr->area_name;
  533.             }
  534.       if (tot_areas > 0)
  535.          {
  536.          for (i = 0; i < tot_areas; i++)
  537.             {
  538.             if (strcmp (aptr->msg_path, areas[i]->msg_path) == 0)
  539.                {
  540.                aptr->msgs_in_area = areas[i]->msgs_in_area;
  541.                aptr->flags |= SIBLING;
  542.                areas[i]->flags |= PARENT;
  543.  
  544.                /* Now add to the PARENT */
  545.                aptr1 = areas[i];
  546.  
  547.                 aptr1->zone = (int *) realloc ((char *) aptr1->zone, (unsigned) (sizeof(int) *
  548.                   (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  549.                 aptr1->net = (int *) realloc ((char *) aptr1->net, (unsigned) (sizeof(int) *
  550.                   (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  551.                 aptr1->node = (int *) realloc ((char *) aptr1->node, (unsigned) (sizeof (int) *
  552.                   (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  553.  
  554.                 #if STATS
  555.                     aptr1->msgs_scanned = (int *) realloc ((char *) aptr1->msgs_scanned, (unsigned) (sizeof (int) *
  556.                       (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  557.                 #endif
  558.  
  559.                 aptr1->handle = (int *) realloc ((char *) aptr1->handle, (unsigned) (sizeof (int) *
  560.                    (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  561.                 aptr1->aname = (char **) realloc ((char *) aptr1->aname, (unsigned) (sizeof (char *) *
  562.                    (aptr1->num_nodes + aptr->num_nodes + seen_aka)));
  563.  
  564.                 if ((aptr1->net == NULL) || (aptr1->node == NULL) || (aptr1->zone == NULL) ||
  565.                    (aptr1->handle == NULL) || (aptr1->aname == NULL))
  566.                     {
  567.                     printf (areaserr);
  568.                     exit (2);
  569.                     }
  570.                 for (k = aptr1->num_nodes; k < aptr1->num_nodes+aptr->num_nodes; k++)
  571.                     {
  572.                     aptr1->zone[k] = aptr->zone[k-aptr1->num_nodes];
  573.                     aptr1->net[k] = aptr->net[k-aptr1->num_nodes];
  574.                     aptr1->node[k] = aptr->node[k-aptr1->num_nodes];
  575.  
  576.                     #if STATS
  577.                         aptr1->msgs_scanned[k] = 0;
  578.                     #endif
  579.                     }
  580.  
  581.                 for (k = aptr1->num_nodes; k < aptr1->num_nodes+aptr->num_nodes; k++)
  582.                     {
  583.                     aptr1->handle[k] = aptr->handle[k-aptr1->num_nodes];
  584.                     aptr1->aname[k] = aptr->aname[k-aptr1->num_nodes];
  585.                     }
  586.  
  587.                aptr1->num_nodes += aptr->num_nodes;
  588.                 sort_em (&(aptr1->zone[0]), &(aptr1->net[0]), &(aptr1->node[0]),
  589.                     aptr1->num_nodes, 1, &(aptr1->handle[0]),
  590.                   &(aptr1->aname[0]));
  591.                break;
  592.                }
  593.             }
  594.          if (i >= tot_areas)
  595.             {
  596.             aptr->msgs_in_area = (int *) calloc (1, sizeof (int));
  597.             *(aptr->msgs_in_area) = -1;
  598.             }
  599.          }
  600.       else
  601.          {
  602.          aptr->msgs_in_area = (int *) calloc (1, sizeof (int));
  603.         *(aptr->msgs_in_area) = -1;
  604.          }
  605.  
  606. #if DEBUG
  607. printf ("\nRECAP1\n\n");
  608. for (i = 0; i < tot_areas; i++)
  609. {
  610. printf ("AREA #%2d: DIR='%s' NAME='%s'\n", i, areas[i]->msg_path,
  611. areas[i]->area_name);
  612. for (k = 0; k < areas[i]->num_nodes; k++)
  613. printf ("NODE %d=%d:%d/%d:%s\n", k, areas[i]->zone[k], areas[i]->net[k], areas[i]->node[k], areas[i]->aname[k]);
  614. }
  615. #endif
  616.  
  617.         sort_em (&(aptr->zone[0]), &(aptr->net[0]), &(aptr->node[0]),
  618.             aptr->num_nodes, 1, &(aptr->handle[0]), &(aptr->aname[0]));
  619.  
  620. #if DEBUG
  621. for (k = 0; k < aptr->num_nodes; k++)
  622. printf ("Net/node[%d] = %d:%d/%d\n", k, aptr->zone[k], aptr->net[k], aptr->node[k]);
  623. #endif
  624.  
  625.         ++tot_areas;
  626.         }
  627.  
  628. #if DEBUG
  629. printf ("\nRECAP\n\n");
  630. for (i = 0; i < tot_areas; i++)
  631. {
  632. printf ("AREA #%2d: DIR='%s' NAME='%s'\n", i, areas[i]->msg_path,
  633. areas[i]->area_name);
  634. for (k = 0; k < areas[i]->num_nodes; k++)
  635. printf ("NODE %d=%d:%d/%d:%s\n", k, areas[i]->zone[k], areas[i]->net[k], areas[i]->node[k], areas[i]->aname[k]);
  636. }
  637. #endif
  638.  
  639.     free ((char *) tmpzone);
  640.     free ((char *) tmpnet);
  641.     free ((char *) tmpnode);
  642.     fclose (f);
  643.     if (num_zone)
  644.     {
  645.         sort_em (&(zone_zone[1]), &(zone_net[1]), &(zone_node[1]), num_zone-1, 0, NULL, NULL);
  646.     }
  647.     return (0);
  648. }
  649.  
  650. void sort_em(
  651.     int   zones[],
  652.     int   nets[],
  653.     int   nodes[],
  654.     int   num_nodes,
  655.     int   others,
  656.     int   o1[],
  657.     char *o2[])
  658. {
  659.     register int i, j;
  660.     int tmp1, tmp2, tmp3, swaps;
  661.     char *tmp4;
  662.  
  663.     i = 0;
  664.     j = num_nodes;
  665.     swaps = 1;
  666.  
  667.     while (swaps)
  668.     {
  669.         for (j--, i = 0, swaps = 0; i < j; i++)
  670.         {
  671.             if ((nets[i] > nets[i+1]) ||
  672.                  ((nets[i] == nets[i+1]) && (nodes[i] > nodes[i+1])))
  673.                 {
  674.             tmp3 = zones[i];
  675.                 tmp1 = nets[i];
  676.                 tmp2 = nodes[i];
  677.             zones[i] = zones[i+1];
  678.                 nets[i] = nets[i+1];
  679.                 nodes[i] = nodes[i+1];
  680.             zones[i+1] = tmp3;
  681.                 nets[i+1] = tmp1;
  682.                 nodes[i+1] = tmp2;
  683.             if (others)
  684.                {
  685.                tmp1 = o1[i];
  686.                tmp4 = o2[i];
  687.                o1[i] = o1[i+1];
  688.                o2[i] = o2[i+1];
  689.                o1[i+1] = tmp1;
  690.                o2[i+1] = tmp4;
  691.                }
  692.             ++swaps;
  693.                 }
  694.          }
  695.       }
  696.  
  697. /*
  698.   for (i = 0; i < num_nodes; i++)
  699.   {
  700.     printf ("%d = %d/%d\n", i, nets[i], nodes[i]);
  701.   }
  702.  
  703.     for (i = 0; i < num_nodes; i++)
  704.         for (j = i+1; j < num_nodes; j++)
  705.             {
  706.             if ((nets[j] < nets[i]) ||
  707.                  ((nets[j] == nets[i]) && (nodes[j] < nodes[i])))
  708.                 {
  709.                 tmp1 = nets[i];
  710.                 tmp2 = nodes[i];
  711.                 nets[i] = nets[j];
  712.                 nodes[i] = nodes[j];
  713.                 nets[j] = tmp1;
  714.                 nodes[j] = tmp2;
  715.                 }
  716.             }
  717. */
  718. }
  719.  
  720.