1: /* pathalias -- by steve bellovin, as told to peter honeyman */ 2: #ifndef lint 3: static char *sccsid = "@(#)printit.c 8.2 (down!honey) 86/01/29"; 4: #endif 5: 6: #include "def.h" 7: 8: /* use lots of char bufs -- profiling indicates this costs about 5 kbytes */ 9: 10: /* in practice, even the longest paths are < 100 bytes */ 11: #define PSIZE 512 12: 13: printit() 14: { link *l; 15: char pbuf[PSIZE]; 16: 17: /* print home */ 18: if (Cflag) 19: printf("%ld\t", (long) Home->n_cost); 20: printf("%s\t%%s\n", Home->n_name); 21: 22: strcpy(pbuf, "%s"); 23: for (l = Home->n_link; l; l = l->l_next) { 24: if (l->l_flag & LTREE) { 25: preorder(l, pbuf); 26: strcpy(pbuf, "%s"); 27: } 28: } 29: } 30: 31: /* preorder traversal of shortest path tree */ 32: preorder(l, ppath) 33: register link *l; 34: char *ppath; 35: { 36: register node *n; 37: char npath[PSIZE]; 38: 39: setpath(l, ppath, npath); 40: n = l->l_to; 41: if ((n->n_flag & NNET) || ISADOMAIN(n)) 42: printnet(n, npath, n->n_cost); 43: else 44: printhost(n, npath, n->n_cost); 45: for (l = n->n_link; l; l = l->l_next) 46: if (l->l_flag & LTREE) 47: preorder(l, npath); 48: } 49: 50: setpath(l, ppath, npath) 51: link *l; 52: register char *ppath, *npath; 53: { 54: register node *next; 55: char netchar; 56: extern char *hostpath(); 57: 58: next = l->l_to; 59: /* 60: * for magic @-% conversion. 61: * assume that gateways to domains want no @'s 62: */ 63: if (next->n_parent->n_flag & ATSIGN || ISADOMAIN(next)) 64: next->n_flag |= ATSIGN; 65: 66: /* special handling for aliases , domains, and nets */ 67: if ((l->l_flag & LALIAS) || (next->n_flag & NNET) || ISADOMAIN(next)) { 68: strcpy(npath, ppath); 69: return; 70: } 71: 72: netchar = NETCHAR(l); 73: if (netchar == '@') 74: if (next->n_flag & ATSIGN) 75: netchar = '%'; /* shazam? shaman? */ 76: else 77: next->n_flag |= ATSIGN; 78: 79: /* remainder should be a sprintf -- foo on '%' as an operator */ 80: for ( ; *npath = *ppath; ppath++) { 81: if (*ppath == '%') { 82: switch(ppath[1]) { 83: case 's': 84: ppath++; 85: npath = hostpath(npath, l, netchar); 86: break; 87: 88: case '%': 89: *++npath = *++ppath; 90: npath++; 91: break; 92: 93: default: 94: fprintf(stderr, "%s: %%%c found in setpath\n", 95: ProgName, ppath[1]); 96: badmagic(1); 97: break; 98: } 99: } else 100: npath++; 101: } 102: } 103: 104: char * 105: hostpath(path, l, netchar) 106: register char *path; 107: register link *l; 108: char netchar; 109: { 110: register node *prev; 111: 112: prev = l->l_to->n_parent; 113: if (NETDIR(l) == LLEFT) { 114: /* host!user */ 115: strcpy(path, l->l_to->n_name); 116: path += strlen(path); 117: while (ISADOMAIN(prev)) { 118: strcpy(path, prev->n_name); 119: path += strlen(path); 120: prev = prev->n_parent; 121: } 122: *path++ = netchar; 123: if (netchar == '%') 124: *path++ = '%'; 125: *path++ = '%'; 126: *path++ = 's'; 127: } else { 128: /* %s@host */ 129: *path++ = '%'; 130: *path++ = 's'; 131: *path++ = netchar; 132: if (netchar == '%') 133: *path++ = '%'; 134: strcpy(path, l->l_to->n_name); 135: path += strlen(path); 136: while (ISADOMAIN(prev)) { 137: strcpy(path, prev->n_name); 138: path += strlen(path); 139: prev = prev->n_parent; 140: } 141: } 142: return(path); 143: } 144: 145: STATIC 146: printhost(n, path, cost) 147: node *n; 148: char *path; 149: Cost cost; 150: { 151: /* skip private hosts */ 152: if ((n->n_flag & ISPRIVATE) == 0) { 153: if (Cflag) 154: printf("%ld\t", (long) cost); 155: fputs(n->n_name, stdout); 156: putchar('\t'); 157: puts(path); 158: } 159: } 160: 161: STATIC 162: printnet(n, path, cost) 163: node *n; 164: char *path; 165: Cost cost; 166: { 167: node *parent; 168: 169: /* print domains only */ 170: if (!ISADOMAIN(n)) 171: return; 172: 173: /* print top-level domain */ 174: if (!ISADOMAIN(n->n_parent)) { 175: if (n->n_flag & ISPRIVATE) 176: fprintf(stderr, "%s: warning: private top-level domain %s ignored\n", ProgName, n->n_name); 177: else 178: printdomain(n, path, cost); 179: return; 180: } 181: 182: /* remainder is for subdomains */ 183: 184: /* don't print if it has a non-private ancestor */ 185: for (parent = n->n_parent; parent; parent = parent->n_parent) 186: if (ISADOMAIN(parent) && (parent->n_flag & ISPRIVATE) == 0) 187: return; 188: 189: /* don't print if this domain is also private */ 190: if (n->n_flag & ISPRIVATE) 191: return; 192: 193: /* ancestors all private, this domain not private */ 194: printdomain(n, path, cost); 195: } 196: 197: STATIC 198: printdomain(n, path, cost) 199: node *n; 200: char *path; 201: Cost cost; 202: { 203: /* skip subdomains, since the gateway to the parent suffices */ 204: if (ISADOMAIN(n->n_parent)) 205: return; 206: if (Cflag) 207: printf("%ld\t", (long) cost); 208: do { 209: fputs(n->n_name, stdout); 210: n = n->n_parent; 211: } while (ISADOMAIN(n)); 212: putchar('\t'); 213: puts(path); 214: }