/******************************************************************* * Translate the so-called explicit or "full" routing * list format back to the 'normal' (terse) routing * list format. * * Convert: * Path #1 #2 #3: <#4 #5> ... <#6 #7> * To: * #3 #1 - #2: #5 ... #7 ; * * Key: * #1 = Source device number. * #2 = Destination device number. * #3 = Alternate path number. * #4 = First device in path (same as #1). * #5 = First port number in path. * ... = All the intermediate hops. * #6 = Last device hop in path (same as #2). * #7 = Last port number in path. * * Usage: * 1. Makes 'netinfo.fullpath': * router -fullpath netinfo * 2. Edit or process 'netinfo.fullpath', as wished. * 3. Convert back to normal routing table: * translate_paths netinfo.fullpath * * Compile: * gcc -O -g translate_paths.c -o translate_paths * *******************************************************************/ /*******************************************************************/ /* This is a general purpose shell, or framework, for beginning */ /* to write any program that uses file IO from files that are */ /* specified on the command line. */ /* */ /* Invocation: */ /* This program expects the source file to be the first file */ /* on the command-line. If no files are specified, on the */ /* command-line, it will prompt you. By default, if no */ /* destination file name is specified, it will write its */ /* output to a file of the same name as the source, but with */ /* a ".rte" suffix. If you wish to write the file to another */ /* name, then specify that name as the second command-line */ /* argument. */ /*******************************************************************/ #include /* Read_next line from file, filtering all comments. */ void ReadLine( FILE *iz, char *word ) { int i=0, line_crossed=0; char ch=32, och=32; while ((!feof(iz)) && (ch!=10)) { ch = getc(iz); if (!feof(iz)) { if (ch!=10) { word[i]=ch; i = i + 1; if (i==1024) { word[i-1]='\0'; printf("ERROR:%cLine too long '%s'.\n", 7, word); } } och = ch; } } word[i] = '\0'; } /*....................................................................... . NEXT_WORD - accepts a line of text, and returns with the . . next word in that text in the third parameter, the original line . . is shortened from the beginning so that the word is removed. . . If the line encountered is empty, then the word returned will be . . empty. . . NEXTWORD can parse on an arbitrary number of delimiters, and it . . returns everthing that was cut away in the second parameter. . .......................................................................*/ void next_word( char *line, char *pre_trash, char *word, char *delim ) { int i=0, j=0, k=0, m=0, flag=1; /* Eat away preceding garbage */ while ((line[i]!='\0') && (flag)) { j = 0; while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1; if (line[i]==delim[j]) { pre_trash[k] = line[i]; k = k + 1; i = i + 1; } else flag = 0; } /* Copy the word until the next delimiter. */ while ((line[i]!='\0') && (!flag)) { word[m] = line[i]; m = m + 1; i = i + 1; if (line[i]!='\0') { j = 0; while ((delim[j]!='\0') && (line[i]!=delim[j])) j = j + 1; if (line[i]==delim[j]) flag = 1; } } /* Shorten line. */ j = 0; while (line[i]!='\0') { line[j] = line[i]; j = j + 1; i = i + 1; } /* Terminate the char-strings. */ line[j] = '\0'; pre_trash[k] = '\0'; word[m] = '\0'; } /*......................................................................*/ /* MAIN - */ /*......................................................................*/ main( int argc, char *argv[] ) { char fname[2][2560], trsh[500], wrd1[500], wrd2[500], wrd3[500], tmpwrd[1000], line[2000]; int i,j,k, verbose=0, lcnt=0; FILE *infile, *outfile; /* Get any command line arguments. */ infile = 0; i = 1; k = 0; fname[1][0] = '\0'; while (argc>i) { /*argument*/ if (argv[i][0]=='-') { /*optionflag*/ if ((argv[i][1]=='v') || (argv[i][1]=='V')) verbose = 1; else {printf("\nERROR: Unknown command line option /%s/.\n", argv[i]); exit(0); } } /*optionflag*/ else { /*file*/ strcpy(fname[k],argv[i]); if (k==0) { infile = fopen(fname[k],"r"); } else if (k>1) { printf("\nERROR: Too many file names on command line.\n"); exit(0); } k = k + 1; } /*file*/ i = i + 1; } /*argument*/ while (infile==0) { printf("What is the SOURCE file name ? "); scanf("%s",fname[0]); infile = fopen(fname[0],"r"); } /* Allow user to specify an optional destination file name. */ if (fname[1][0]=='\0') { /* Make the output file name. */ strcpy(fname[1], fname[0]); i = strlen(fname[1]) - 1; while ((i>0) && (fname[1][i]!='.')) i = i - 1; if (fname[1][i]=='.') fname[1][i] = '\0'; strcat(fname[1],".rte"); } if (strcmp(fname[0],fname[1])==0) {printf("ERROR: I can't allow you to write over the source files.\n"); exit(1);} printf("\n Writing output to file %s\n\n", fname[1]); outfile = fopen(fname[1],"w"); if (outfile==0) {printf("ERROR: Cannot open '%s' for writing.\n", fname[1]); exit(1);} /* ---------------------- */ /* Put your program HERE: */ ReadLine( infile, line ); next_word( line, trsh, wrd1, " :"); while (!feof(infile)) { /* Expect lines like: Path #1 #2 #3: <#4 #5> ... <#6 #7> Convert them to: #3 #1 - #2: #5 ... #7 ; */ lcnt++; if (strcmp(wrd1,"Path")!=0) /* Check for line synch. */ { printf("ERROR: First word on line not 'Path' but '%s' on line %d.\n", wrd1, lcnt); exit(0); } next_word( line, trsh, wrd1, " "); next_word( line, trsh, wrd2, " "); next_word( line, trsh, wrd3, " :"); fprintf(outfile,"%s %s - %s:", wrd3, wrd1, wrd2 ); next_word( line, trsh, wrd1, " <:"); while (wrd1[0]!='\0') { next_word( line, trsh, wrd2, " >"); if (wrd2[0]!='-') fprintf(outfile," %s", wrd2); next_word( line, trsh, wrd1, " <>"); } fprintf(outfile," ;\n"); ReadLine( infile, line ); next_word( line, trsh, wrd1, " :"); } /* ---------------------- */ fclose(infile); fclose(outfile); }