home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.aix
- Path: sparky!uunet!newsstand.cit.cornell.edu!gibbon!len
- From: len@gibbon.cornell.edu ()
- Subject: installation images directory table of contents
- Message-ID: <1993Jan6.182557.28955@mail.cornell.edu>
- Sender: news@mail.cornell.edu
- Nntp-Posting-Host: gibbon.cit.cornell.edu
- Nntp-Posting-User: @cornell.edu
- Organization: Cornell University CIT
- Date: Wed, 6 Jan 1993 18:25:57 GMT
- Lines: 211
-
-
- This problem occurs in the smit menu "install software with updates",
- preliminary to executing the command
-
- installp -qa -d/usr/sys/inst.images -X ...
-
- From this menu, my AIX 3.2 install server presents over 2200 lines of
- program product and update information, sorted in essentially random order.
- The order is roughly derived from the order in the table of contents
- file .toc, built by the inutoc command. Apparently, inutoc reads
- the directory /usr/sys/inst.images in its actual random order and build its
- .toc file in the reverse of the order it finds.
-
- My install server now has 579 program products and updates -- apparently
- this is more than the developers of installp planned for.
-
- I called IBM defect support, apparently inutoc is "broken as designed" --
- I submitted a design change request through my IBM representative, but we
- don't expect any quick action.
-
- Not expecting any help from IBM, I wrote this little C program to sort the
- .toc file. If you can use this, please feel free. After running this
- program and replacing the .toc file with the sorted version, the list
- produced by smit is still not perfectly sorted, but I can live with it:
-
- ------------------------------------------------------------------
-
- /* program to sort a .toc file -- crude, but works
- *
- * default input /inst.images/.toc, output /tmp/.toc.new,
- * follow by mv /tmp/.toc.new .toc if satisfied
- *
- * program takes 2 parameters for input file and output file if desired
- *
- * apparently the format for a .toc record is head{body}tail
- * except for the first record, some kind of header
- *
- */
-
- #include <stdio.h>
- #include <string.h>
-
- /* these are guesses */
- #define MAX_RECORDS 2048
- #define RECORD_SIZE 20480
-
- char *malloc();
-
- /* defaults for input parameters */
- char *ifile="/usr/sys/inst.images/.toc";
- char *ofile="/tmp/.toc.new";
-
- /* globals for the table of contents records and sizes */
- char *records[MAX_RECORDS];
- int sizes[MAX_RECORDS];
-
- main(argc,argv) int argc; char **argv; {
- int i;
- int got_eof;
- FILE *ifp, *ofp;
- int head, body, tail;
- int n;
- char *pbuf;
-
- /* process input arguments */
- if (argc>1) ifile=argv[1];
- if (argc>2) ofile=argv[2];
- if ((ifp=fopen(ifile,"r")) == NULL) {
- fprintf(stderr,"can't open %s\n",ifile);
- exit(1);
- }
- if ((ofp=fopen(ofile,"w")) == NULL) {
- fprintf(stderr,"can't open %s\n",ofile);
- exit(1);
- }
-
- /* read record 0: special case */
- if ((pbuf=malloc(RECORD_SIZE)) == NULL) {
- fprintf(stderr, "can't malloc %d bytes\n",RECORD_SIZE);
- exit(1);
- }
- records[0]=pbuf;
- got_eof = read_until('\n',ifp, pbuf, &head);
- sizes[0]=head;
-
- /* all other records are of form head{body}tail --
- * the body, enclosed in curly brackets, may contain other sets of
- * curly brackets
- */
- n = 1;
- while(!feof(ifp)) {
- head=0;
- body=0;
- if ((pbuf=malloc(RECORD_SIZE)) == NULL) {
- fprintf(stderr, "can't malloc %d bytes\n",RECORD_SIZE);
- fprintf(stderr, "program abortina\n");
- exit(1);
- }
- records[n]=pbuf;
- got_eof = read_until('{',ifp, pbuf, &head);
- if (got_eof < 0) {
- sizes[n++]=head;
- break;
- }
-
- got_eof = read_and_stack('}', '{', ifp, &pbuf[head], &body);
- got_eof = read_until('\n',ifp, &pbuf[head+body], &tail);
- sizes[n++]=head+body+tail;
-
- if (n > MAX_RECORDS) {
- fprintf(stderr, "%d records > MAX_RECORDS=%d\n", n,MAX_RECORDS);
- fprintf(stderr, "recompile with larger MAX_RECORDS\n");
- fprintf(stderr, "program abortina\n");
- exit(1);
- }
- }
-
- /* sort here
- *
- * leave first record alone, sort the others
- */
- sort(1, n-1);
-
- /* all done, write the sorted file */
- for (i=0; i<n; i++)
- fwrite(records[i], 1, sizes[i], ofp);
- fclose(ifp);
- fclose(ofp);
- printf("%s sorted, result in %s\n\n", ifile,ofile);
- }
-
-
- /* read_and_stack is called to look for the closing '}', stacking '{' chars
- * along the way
- */
- int
- read_and_stack(stopc, stackc, ifp, buf, pcount)
- int stopc, stackc; FILE *ifp; char *buf; int *pcount;
- {
- int i, c, stacked;
-
- for (i=0, stacked=0; ; i++) {
- c = getc(ifp);
- buf[i] = c;
- if (c==stackc)
- stacked++;
- if (c==stopc) {
- if (stacked==0) {
- i++;
- break;
- }
- stacked--;
- }
- if (feof(ifp)) {
- *pcount = i;
- return -1;
- }
- }
-
- *pcount = i;
- return 0;
- }
-
- /* read_until is called to read up to the next '{', or the next '\n'
- */
- int
- read_until(stopc, ifp, buf, pcount)
- int stopc; FILE *ifp; char *buf; int *pcount;
- {
- int i;
- int c;
- i = 0;
- do {
- c = getc(ifp);
- buf[i] = c;
- if (feof(ifp)) {
- *pcount = i;
- return -1;
- }
- i++;
- }
- while (c != stopc);
- *pcount = i;
- return 0;
- }
-
- /* a standard swap */
- swap(start,a,b) int a,b; {
- char *swap_ptr;
- int swap_int;
- swap_ptr=records[start+a];
- records[start+a]=records[start+b];
- records[start+b]=swap_ptr;
- swap_int=sizes[start+a];
- sizes[start+a]=sizes[start+b];
- sizes[start+b]=swap_int;
- }
-
- /* standard sort straight from K&R */
- sort(start, how_many) int start, how_many; {
- char **p;
- int gap, i, j;
- p=&records[start];
- for (gap=how_many/2; gap>0; gap /=2)
- for (i=gap; i<how_many; i++)
- for (j=i-gap; j>=0; j-=gap) {
- if(strcmp(p[j],p[j+gap]) <= 0)
- break;
- swap(start,j,j+gap);
- }
- }
-