home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / unix / aix / 13058 < prev    next >
Encoding:
Text File  |  1993-01-06  |  5.5 KB  |  224 lines

  1. Newsgroups: comp.unix.aix
  2. Path: sparky!uunet!newsstand.cit.cornell.edu!gibbon!len
  3. From: len@gibbon.cornell.edu ()
  4. Subject: installation images directory table of contents
  5. Message-ID: <1993Jan6.182557.28955@mail.cornell.edu>
  6. Sender: news@mail.cornell.edu
  7. Nntp-Posting-Host: gibbon.cit.cornell.edu
  8. Nntp-Posting-User: @cornell.edu
  9. Organization: Cornell University CIT
  10. Date: Wed, 6 Jan 1993 18:25:57 GMT
  11. Lines: 211
  12.  
  13.  
  14. This problem occurs in the smit menu "install software with updates",
  15. preliminary to executing the command
  16.  
  17.         installp -qa -d/usr/sys/inst.images -X ...
  18.  
  19. From this menu, my AIX 3.2 install server presents over 2200 lines of
  20. program product and update information, sorted in essentially random order.
  21. The order is roughly derived from the order in the table of contents
  22. file .toc, built by the inutoc command.  Apparently, inutoc reads
  23. the directory /usr/sys/inst.images in its actual random order and build its
  24. .toc file in the reverse of the order it finds.
  25.  
  26. My install server now has 579 program products and updates -- apparently
  27. this is more than the developers of installp planned for.
  28.  
  29. I called IBM defect support, apparently inutoc is "broken as designed" --
  30. I submitted a design change request through my IBM representative, but we
  31. don't expect any quick action.
  32.  
  33. Not expecting any help from IBM, I wrote this little C program to sort the
  34. .toc file.  If you can use this, please feel free.  After running this
  35. program and replacing the .toc file with the sorted version, the list
  36. produced by smit is still not perfectly sorted, but I can live with it:
  37.  
  38. ------------------------------------------------------------------
  39.  
  40. /* program to sort a .toc file -- crude, but works
  41.  *
  42.  * default input /inst.images/.toc, output /tmp/.toc.new,
  43.  * follow by mv /tmp/.toc.new .toc if satisfied
  44.  *
  45.  * program takes 2 parameters for input file and output file if desired
  46.  *
  47.  * apparently the format for a .toc record is head{body}tail
  48.  * except for the first record, some kind of header
  49.  *
  50.  */
  51.  
  52. #include <stdio.h>
  53. #include <string.h>
  54.  
  55. /* these are guesses */
  56. #define MAX_RECORDS 2048
  57. #define RECORD_SIZE 20480
  58.  
  59. char *malloc();
  60.  
  61. /* defaults for input parameters */
  62. char *ifile="/usr/sys/inst.images/.toc";
  63. char *ofile="/tmp/.toc.new";
  64.  
  65. /* globals for the table of contents records and sizes */
  66. char *records[MAX_RECORDS];
  67. int sizes[MAX_RECORDS];
  68.  
  69. main(argc,argv) int argc; char **argv; {
  70.     int i;
  71.     int got_eof;
  72.     FILE *ifp, *ofp;
  73.     int head, body, tail;
  74.     int n;
  75.     char *pbuf;
  76.  
  77.     /* process input arguments */
  78.     if (argc>1) ifile=argv[1];
  79.     if (argc>2) ofile=argv[2];
  80.     if ((ifp=fopen(ifile,"r")) == NULL) {
  81.     fprintf(stderr,"can't open %s\n",ifile);
  82.     exit(1);
  83.     }
  84.     if ((ofp=fopen(ofile,"w")) == NULL) {
  85.     fprintf(stderr,"can't open %s\n",ofile);
  86.     exit(1);
  87.     }
  88.  
  89.     /* read record 0: special case */
  90.     if ((pbuf=malloc(RECORD_SIZE)) == NULL) {
  91.     fprintf(stderr, "can't malloc %d bytes\n",RECORD_SIZE);
  92.     exit(1);
  93.     }
  94.     records[0]=pbuf;
  95.     got_eof = read_until('\n',ifp, pbuf, &head);
  96.     sizes[0]=head;
  97.  
  98.     /* all other records are of form head{body}tail --
  99.      * the body, enclosed in curly brackets, may contain other sets of
  100.      * curly brackets
  101.      */
  102.     n = 1;
  103.     while(!feof(ifp)) {
  104.     head=0;
  105.     body=0;
  106.     if ((pbuf=malloc(RECORD_SIZE)) == NULL) {
  107.         fprintf(stderr, "can't malloc %d bytes\n",RECORD_SIZE);
  108.         fprintf(stderr, "program abortina\n");
  109.         exit(1);
  110.         }
  111.     records[n]=pbuf;
  112.     got_eof = read_until('{',ifp, pbuf, &head);
  113.     if (got_eof < 0) {
  114.         sizes[n++]=head;
  115.         break;
  116.         }
  117.  
  118.     got_eof = read_and_stack('}', '{', ifp, &pbuf[head], &body);
  119.     got_eof = read_until('\n',ifp, &pbuf[head+body], &tail);
  120.     sizes[n++]=head+body+tail;
  121.  
  122.     if (n > MAX_RECORDS) {
  123.         fprintf(stderr, "%d records > MAX_RECORDS=%d\n", n,MAX_RECORDS);
  124.         fprintf(stderr, "recompile with larger MAX_RECORDS\n");
  125.         fprintf(stderr, "program abortina\n");
  126.         exit(1);
  127.         }
  128.     }
  129.  
  130.     /* sort here
  131.      *
  132.      * leave first record alone, sort the others
  133.      */
  134.     sort(1, n-1);
  135.  
  136.     /* all done, write the sorted file */
  137.     for (i=0; i<n; i++)
  138.     fwrite(records[i], 1, sizes[i], ofp);
  139.     fclose(ifp);
  140.     fclose(ofp);
  141.     printf("%s sorted, result in %s\n\n", ifile,ofile);
  142. }
  143.  
  144.  
  145. /* read_and_stack is called to look for the closing '}', stacking '{' chars
  146.  * along the way
  147.  */
  148. int
  149. read_and_stack(stopc, stackc, ifp, buf, pcount)
  150. int stopc, stackc; FILE *ifp; char *buf; int *pcount;
  151. {
  152.    int i, c, stacked;
  153.  
  154.    for (i=0, stacked=0; ; i++) {
  155.     c = getc(ifp);
  156.     buf[i] = c;
  157.     if (c==stackc)
  158.         stacked++;
  159.     if (c==stopc) {
  160.         if (stacked==0) {
  161.         i++;
  162.         break;
  163.         }
  164.         stacked--;
  165.         }
  166.     if (feof(ifp)) {
  167.         *pcount = i;
  168.         return -1;
  169.         }
  170.     }
  171.  
  172.    *pcount = i;
  173.    return 0;
  174. }
  175.  
  176. /* read_until is called to read up to the next '{', or the next '\n'
  177.  */
  178. int
  179. read_until(stopc, ifp, buf, pcount)
  180. int stopc; FILE *ifp; char *buf; int *pcount;
  181. {
  182.    int i;
  183.    int c;
  184.    i = 0;
  185.    do {
  186.     c = getc(ifp);
  187.     buf[i] = c;
  188.     if (feof(ifp)) {
  189.         *pcount = i;
  190.         return -1;
  191.         }
  192.     i++;
  193.     }
  194.    while (c != stopc);
  195.    *pcount = i;
  196.    return 0;
  197. }
  198.  
  199. /* a standard swap */
  200. swap(start,a,b) int a,b; {
  201.     char *swap_ptr;
  202.     int swap_int;
  203.     swap_ptr=records[start+a];
  204.     records[start+a]=records[start+b];
  205.     records[start+b]=swap_ptr;
  206.     swap_int=sizes[start+a];
  207.     sizes[start+a]=sizes[start+b];
  208.     sizes[start+b]=swap_int;
  209. }
  210.  
  211. /* standard sort straight from K&R */
  212. sort(start, how_many) int start, how_many; {
  213.     char **p;
  214.     int gap, i, j;
  215.     p=&records[start];
  216.     for (gap=how_many/2; gap>0; gap /=2)
  217.     for (i=gap; i<how_many; i++)
  218.         for (j=i-gap; j>=0; j-=gap) {
  219.         if(strcmp(p[j],p[j+gap]) <= 0)
  220.             break;
  221.         swap(start,j,j+gap);
  222.         }
  223. }
  224.