GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 1 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 1 /******************************************************************** 2 * wilkinson 3 * 3.33VMS 4 * 1995/05/26 10:45 5 * gopher_root1:[gopher.g2.vms2_13.object]GDgopherdir.c,v 6 * Exp 7 * 8 * Paul Lindner, University of Minnesota CIS. 9 * 10 * Copyright 1991, 1992 by the Regents of the University of Minnesota 11 * see the file "Copyright" in the distribution for conditions of use. 12 ********************************************************************* 13 * MODULE: GDgopherdir.c 14 * Implement gopher directory routines 15 ********************************************************************* 16 * Revision History: 17 * GDgopherdir.c,v 18 * Revision 3.33VMS 1995/05/26 10:45 wilkinson 19 * Consolodate VMS/Unix source code for server as well as client 20 * 21 * Revision 3.33 1995/02/17 18:34:09 lindner 22 * Fix stupid bug 23 * 24 * Revision 3.32 1995/02/16 22:32:43 lindner 25 * HTML icon support 26 * 27 * Revision 3.31 1995/02/13 19:09:25 lindner 28 * Fix for link updating 29 * 30 * Revision 3.30 1995/02/06 22:11:26 lindner 31 * Fix for GDsearch comparision 32 * 33 * Revision 3.29 1995/02/01 22:06:22 lindner 34 * Put back GDaddGSmerge, ugh. 35 * 36 * Revision 3.27 1994/10/18 21:36:34 lindner 37 * Remove unused variable 38 * 39 * Revision 3.26 1994/07/21 22:29:00 lindner 40 * misc hacks 41 * 42 * Revision 3.25 1994/07/06 03:01:30 lindner 43 * VMS doesn't have strcoll 44 * 45 * Revision 3.24 1994/06/29 06:47:51 lindner 46 * Use strcoll to sort if GINTERNATIONAL is defined 47 * 48 * Revision 3.23 1994/06/29 05:45:54 lindner 49 * Mods to pump tickets to the net 50 * 51 * Revision 3.22 1994/04/27 19:21:37 lindner 52 * Fix for semicolons after Debugmsg 53 * 54 * Revision 3.21 1994/04/25 03:36:56 lindner 55 * Modifications for Debug() and mismatched NULL arguments, added Debugmsg GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 2 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 56 * 57 * Revision 3.20 1994/04/21 21:24:57 lindner 58 * Fix fcn header 59 * 60 * Revision 3.19 1994/04/19 14:32:27 lindner 61 * Change GD and GSfromLink routines to use FIO 62 * 63 * Revision 3.18 1994/04/13 04:28:58 lindner 64 * Fix for Type=X items 65 * 66 * Revision 3.17 1994/02/20 16:28:19 lindner 67 * Remove dead code for GDtoNetHTML 68 * 69 * Revision 3.16 1994/01/10 03:27:28 lindner 70 * Better GDdeleteGS method, allow ignoring of items by doing a Type=X in a .names file 71 * 72 * Revision 3.15 1993/11/29 01:07:57 lindner 73 * In GDtoLink(), add FALSE argument to GStoLink() call in order to prevent 74 * the Admin and ModDate information from being saved in the user bookmark 75 * file. (Macrides) 76 * 77 * Revision 3.14 1993/11/02 06:15:15 lindner 78 * HTML additions 79 * 80 * Revision 3.13 1993/08/23 20:56:34 lindner 81 * Fix for empty directory in g+ client 82 * 83 * Revision 3.12 1993/08/19 20:51:33 lindner 84 * Mitra comments 85 * 86 * Revision 3.11 1993/08/19 20:24:04 lindner 87 * Mitra's Debug patch 88 * 89 * Revision 3.10 1993/07/29 20:02:16 lindner 90 * Removed dead variables 91 * 92 * Revision 3.9 1993/07/27 05:30:22 lindner 93 * Mondo Debug overhaul from Mitra 94 * 95 * Revision 3.8 1993/07/27 00:30:08 lindner 96 * plus patch from Mitra 97 * 98 * Revision 3.7 1993/07/14 20:37:08 lindner 99 * Negative numbering patches 100 * 101 * Revision 3.6 1993/06/22 06:07:17 lindner 102 * Added Domain= hacks.. 103 * 104 * Revision 3.5 1993/04/15 21:35:12 lindner 105 * Debug code, better .Link processing, better GDfromNet() 106 * 107 * Revision 3.4 1993/03/26 19:50:44 lindner 108 * Mitra fixes for better/clearer fromNet code 109 * 110 * Revision 3.3 1993/03/24 17:04:49 lindner 111 * bad strcmp() can check unmalloced() mem, fixed 112 * GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 3 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 113 * Revision 3.2 1993/03/18 22:13:29 lindner 114 * filtering, compression fixes 115 * 116 * Revision 3.1 1993/02/11 18:03:01 lindner 117 * Initial revision 118 * 119 * Revision 2.1 1993/02/09 22:46:50 lindner 120 * Many additions for gopher+ 121 * 122 * Revision 1.4 1993/01/31 00:22:51 lindner 123 * Changed GDaddGS to merge entries with the same path. 124 * Added GDplusfromNet() to siphon data from network. 125 * GDfromLink now knows about ~/ inside of Path= 126 * Changed GDSearch to ignore leading character. 127 * 128 * Revision 1.3 1992/12/19 04:44:09 lindner 129 * Added GDplustoNet() 130 * 131 * Revision 1.2 1992/12/16 20:37:04 lindner 132 * Added function GDsearch(), does a linear search of a gopher directory 133 * 134 * Revision 1.1 1992/12/10 23:27:52 lindner 135 * gopher 1.1 release 136 * 137 * 138 *********************************************************************/ 139 140 141 #include "GDgopherdir.h" 3051 #include "Malloc.h" 3709 #include "util.h" 3767 3768 #include "String.h" 4285 #include 4534 #include "fileio.h" 5644 #include "Debug.h" 5959 #include "fileio.h" 6138 6139 /*********************************************************************** 6140 ** Stuff for GopherDirObjs 6141 ** 6142 ***********************************************************************/ 6143 6144 6145 GopherDirObj* 6146 GDnew(size) 6147 int size; 6148 { 6149 1 GopherDirObj *temp; 6150 1 6151 1 temp = (GopherDirObj*) malloc(sizeof(GopherDirObj)); 6152 1 6153 1 temp->Gophers = DAnew(size, GSnew, GSinit, GSdestroy, GScpy); 6154 1 6155 1 temp->Title = STRnew(); 6156 1 temp->Location = NULL; 6157 1 temp->currentitem = 1; GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 4 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6158 1 6159 1 GDinit(temp); 6160 1 return(temp); 6161 1 } 6162 6163 6164 void 6165 GDdestroy(gd) 6166 GopherDirObj *gd; 6167 { 6168 1 DAdestroy(gd->Gophers); 6169 1 if (gd->Location != NULL) 6170 1 GSdestroy(gd->Location); 6171 1 6172 1 STRdestroy(gd->Title); 6173 1 free(gd); 6174 1 } 6175 6176 6177 void 6178 GDinit(gd) 6179 GopherDirObj *gd; 6180 { 6181 1 DAinit(gd->Gophers); 6182 1 STRinit(gd->Title); 6183 1 gd->Location = NULL; 6184 1 } 6185 6186 6187 void 6188 GDsetLocation(gd, gs) 6189 GopherDirObj *gd; 6190 GopherObj *gs; 6191 { 6192 1 if (gd->Location == NULL) 6193 1 gd->Location = GSnew(); 6194 1 else 6195 1 GSinit(gd->Location); 6196 1 6197 1 GScpy(gd->Location, gs); 6198 1 } 6199 6200 6201 6202 /** This proc adds a GopherObj to a gopherdir. 6203 It will attempt to merge two items if need be.. 6204 **/ 6205 void 6206 GDaddGSmerge(gd, gs) 6207 GopherDirObj *gd; 6208 GopherObj *gs; 6209 { 6210 1 int num; 6211 1 6212 1 num = GDSearch(gd, GSgetPath(gs)); 6213 1 6214 1 if (num == -1) GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 5 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6215 1 GDaddGS(gd, gs); 6216 1 else { 6217 2 if (GSgetType(gs) == 'X') { 6218 3 gd = GDdeleteGS(gd, num); 6219 3 } else 6220 2 GSmerge(GDgetEntry(gd, num),gs); 6221 2 } 6222 1 } 6223 6224 /* 6225 * This one never tries to merge 6226 */ 6227 6228 void 6229 GDaddGS(gd, gs) 6230 GopherDirObj *gd; 6231 GopherObj *gs; 6232 { 6233 1 6234 1 #ifdef VMS_SERVER 6235 X if (GSgetNum(gs) == -99) { 6236 X return; /** Historical Hidden item for VMS Server **/ 6237 X } 6238 1 #endif 6239 1 if (GSgetType(gs) != 'X') 6240 1 DApush(gd->Gophers, gs); 6241 1 } 6242 6243 6244 /* 6245 * Really weird!!! We need this for qsort, don't know why we can't use 6246 * GScmp... 6247 */ 6248 6249 #define sgn(a) ((a) == 0 ? 0 : (a) < 0 ? -1 : 1) 6250 6251 int 6252 GSqsortcmp(gs1, gs2) 6253 GopherObj **gs1, **gs2; 6254 { 6255 1 if (GSgetTitle(*gs1) == NULL) 6256 1 return(1); 6257 1 if (GSgetTitle(*gs2) == NULL) 6258 1 return(-1); 6259 1 6260 1 /** No numbering set on either entry, or both numbered 6261 1 entries have the same number **/ 6262 1 6263 1 if (GSgetNum(*gs1) == GSgetNum(*gs2)) 6264 1 #ifdef NeXT /* Next has a goofy strcoll */ 6265 X #define strcoll(a,b) strcmp(a,b) 6266 1 #endif 6267 1 return(strcoll(GSgetTitle(*gs1), GSgetTitle(*gs2))); 6268 1 #ifdef NeXT 6269 X #undef strcoll 6270 1 #endif 6271 1 /** If the signs are equal, compare the numbers conventionally **/ GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 6 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6272 1 6273 1 /** N.B. If the signs ARE equal, they cannot be 0 (otherwise we would **/ 6274 1 /** have had the above case, because only the sign of 0 is 0) */ 6275 1 if (sgn(GSgetNum(*gs1)) == sgn(GSgetNum(*gs2))) 6276 1 return(GSgetNum(*gs1) < GSgetNum(*gs2) ? -1 : 1); 6277 1 6278 1 /** The signs must be different, so we can use a conventional test, **/ 6279 1 /** remembering only to say positive numbers go before negative ones **/ 6280 1 return(GSgetNum(*gs1) > GSgetNum(*gs2) ? -1 : 1); 6281 1 } 6282 6283 /* 6284 * Sorts a gopher directory 6285 */ 6286 6287 void 6288 GDsort(gd) 6289 GopherDirObj *gd; 6290 { 6291 1 6292 1 DAsort(gd->Gophers, GSqsortcmp); 6293 1 } 6294 6295 6296 void 6297 GDtoNet(gd, sockfd, fmt, ticket, prefcn) 6298 GopherDirObj *gd; 6299 int sockfd; 6300 GSformat fmt; 6301 char *ticket; 6302 int (*prefcn)(); 6303 6304 { 6305 1 int i; 6306 1 GopherObj *gs; 6307 1 Debugmsg("GDplustoNet\n"); 6308 1 6309 1 if (fmt == GSFORM_HTML) { 6310 2 writestring(sockfd, "
\r\n"); 6311 2 } 6312 1 6313 1 for (i=0; i< GDgetNumitems(gd); i++) { 6314 2 gs = GDgetEntry(gd, i); 6315 2 if (fmt == GSFORM_HTML) 6316 2 writestring(sockfd, "
"); 6317 2 6318 2 if (prefcn) 6319 2 prefcn(gs, sockfd); 6320 2 GStoNet(GDgetEntry(gd, i), sockfd, fmt, ticket); 6321 2 } 6322 1 6323 1 if (fmt == GSFORM_HTML) { 6324 2 writestring(sockfd, "
\r\n"); 6325 2 } 6326 1 } 6327 6328 GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 7 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6329 void 6330 GDplustoNet(gd, sockfd, filter, ticket) 6331 GopherDirObj *gd; 6332 int sockfd; 6333 char **filter; 6334 char *ticket; 6335 { 6336 1 int i; 6337 1 6338 1 for (i=0; i< GDgetNumitems(gd); i++) { 6339 2 GSplustoNet(GDgetEntry(gd, i), sockfd,filter, ticket); 6340 2 } 6341 1 } 6342 6343 #ifdef VMS_SERVER 6344 X 6345 X void 6346 X GDtoNetHTML(gd, sockfd) 6347 X GopherDirObj *gd; 6348 X int sockfd; 6349 X { 6350 X int i; 6351 X 6352 X writestring(sockfd, "\r\n"); 6353 X 6354 X for (i=0; i< GDgetNumitems(gd); i++) { 6355 X writestring(sockfd, "
  • "); 6356 X GStoNetHTML(GDgetEntry(gd, i), sockfd); 6357 X } 6358 X writestring(sockfd, "
  • "); 6359 X } 6360 #endif 6361 6362 /* 6363 * Gopher+ counterpart to GDfromNet() 6364 * returns number of items found 6365 */ 6366 6367 6368 int 6369 GDplusfromNet(gd, fd, eachitem) 6370 GopherDirObj *gd; 6371 int fd; 6372 int (*eachitem)(); 6373 { 6374 1 static GopherObj *TempGopher = NULL; 6375 1 int j, result; 6376 1 char inputline[256]; 6377 1 6378 1 Debugmsg("GDplusfromNet:: start\r\n"); 6379 1 if (TempGopher == NULL) 6380 1 TempGopher = GSnew(); 6381 1 6382 1 /** State: _begin_ **/ 6383 1 6384 1 result = readrecvbuf(fd, inputline, 1); 6385 1 if (result <=0) GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 8 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6386 1 return(0); 6387 1 else if (*inputline == '.') { 6388 2 /*** Read off the rest of the junk... ***/ 6389 2 readline(fd,inputline,sizeof(inputline)); 6390 2 return(0); 6391 2 } 6392 1 else if (*inputline != '+') 6393 1 return(0); 6394 1 6395 1 Debugmsg("after readrecvbuf"); 6396 1 /** State _FirstPlus_ **/ 6397 1 6398 1 result = readtoken(fd, inputline, sizeof(inputline), ':'); 6399 1 if (result <=0) 6400 1 return(result); 6401 1 6402 1 Debugmsg("after readtoken"); 6403 1 if (strcmp(inputline, "INFO")!=0) { 6404 2 return(0); 6405 2 } 6406 1 Debugmsg("after INFO"); 6407 1 /** Read the space **/ 6408 1 readrecvbuf(fd, inputline, 1); 6409 1 6410 1 6411 1 /*** State _FirstINFO_ ***/ 6412 1 6413 1 for (j=0; ; j++) { 6414 2 6415 2 Debugmsg("for start"); 6416 2 6417 2 GSinit(TempGopher); 6418 2 result = GSplusfromNet(TempGopher, fd); 6419 2 6420 2 switch (result) { 6421 3 case MORECOMING: 6422 3 GDaddGS(gd, TempGopher); 6423 3 if (eachitem != NULL) 6424 3 eachitem(); 6425 3 break; 6426 3 6427 3 case FOUNDEOF: 6428 3 GDaddGS(gd, TempGopher); 6429 3 return(j+1); 6430 3 6431 3 case HARDERROR: /** Give up reading - bad read or protocol error **/ 6432 3 return(j); 6433 3 6434 3 case SOFTERROR: /** This one was bad, but we can try for next **/ 6435 3 j= j-1; 6436 3 if (j<0) j=0; 6437 3 break; 6438 3 } 6439 2 6440 2 } /* for */ 6441 1 6442 1 /** Never get here **/ GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 9 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6443 1 } 6444 6445 /* 6446 * Fill up a GopherDirObj with GopherObjs, given a gopher directory coming 6447 * from sockfd. 6448 * 6449 * For each GopherObj retrieved, eachitem() is executed. 6450 * 6451 */ 6452 6453 void 6454 GDfromNet(gd, sockfd, eachitem) 6455 GopherDirObj *gd; 6456 int sockfd; 6457 int (*eachitem)(); 6458 { 6459 1 static GopherObj *TempGopher; 6460 1 int i; 6461 1 char *cp1, *cp2; 6462 1 6463 1 Debugmsg("GDfromNet..."); 6464 1 if (TempGopher == NULL) 6465 1 TempGopher = GSnew(); 6466 1 6467 1 for (; ;) { 6468 2 6469 2 GSinit(TempGopher); 6470 2 i = GSfromNet(TempGopher, sockfd); 6471 2 6472 2 /* In gopher+1.2b2 this routine clears up if GSfromNet returns 6473 2 a failure, better to clear up in GSfromNet so that the 6474 2 system returns in a known state - note that other callers of 6475 2 GSfromNet didn't clean up and crashed! */ 6476 2 6477 2 switch (i) { 6478 3 6479 3 case 0: 6480 3 if (GSgetType(TempGopher) == '3' && 6481 3 ((cp1 = GSgetTitle(TempGopher)) != NULL) && 6482 3 ((cp2 = strchr(cp1, '\n')) != NULL)) { 6483 4 GopherObj *TempG2; 6484 4 do { 6485 5 TempG2 = GSnew(); 6486 5 GScpy(TempG2, TempGopher); 6487 5 GSsetType(TempG2, A_INFO); 6488 5 GSsetTitle(TempG2, cp2+1); 6489 5 *cp2 = '\0'; 6490 5 GSsetTitle(TempGopher, cp1); 6491 5 GDaddGS(gd, TempGopher); 6492 5 TempGopher = TempG2; 6493 5 if ((cp1 = GSgetTitle(TempGopher)) == NULL) 6494 5 break; 6495 5 } while ((cp2 = strchr(cp1, '\n')) != NULL); 6496 4 } 6497 3 GDaddGS(gd, TempGopher); 6498 3 if (eachitem != NULL) eachitem(); 6499 3 break; GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 10 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6500 3 6501 3 case 1: /* . on a line by itself, nothing more */ 6502 3 return; 6503 3 6504 3 case SOFTERROR: /** Unknown object type **/ 6505 3 break; 6506 3 6507 3 case HARDERROR: 6508 3 return; 6509 3 } 6510 2 } 6511 1 } 6512 6513 6514 /* 6515 * Given an open file descriptor and an inited GopherDirobj, 6516 * read in gopher links, and add them to a gopherdir 6517 */ 6518 6519 #ifdef VMS_SERVER 6520 X void 6521 X GDfromLink(gd, fio, host, port, directory, peer, sockfd, access) 6522 X int sockfd; 6523 X int access; 6524 #else 6525 void 6526 GDfromLink(gd, fio, host, port, directory, peer) 6527 #endif 6528 GopherDirObj *gd; 6529 FileIO *fio; 6530 char *host; /** Current Host **/ 6531 int port; /** Current port **/ 6532 char *directory; /** Current directory **/ 6533 char *peer; /** connected client **/ 6534 { 6535 1 GopherObj *gs; 6536 1 int result; 6537 1 char *cp; 6538 1 6539 1 gs = GSnew(); 6540 1 6541 1 while (1) { 6542 2 GSinit(gs); 6543 2 6544 2 result = GSfromLink(gs, fio, host, port,directory, peer); 6545 2 6546 2 if (result == HARDERROR) 6547 2 break; 6548 2 6549 2 if (result == SOFTERROR) 6550 2 continue; 6551 2 6552 2 #ifdef VMS_SERVER 6553 X if (GScanAccess(sockfd, gs, access)) 6554 2 #endif 6555 2 cp = GSgetPath(gs); 6556 2 GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 11 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6557 2 if (*cp == '.') 6558 2 GDaddGSmerge(gd, gs); 6559 2 else 6560 2 GDaddGS(gd, gs); 6561 2 6562 2 if (result == FOUNDEOF) 6563 2 break; 6564 2 6565 2 } 6566 1 6567 1 GSdestroy(gs); 6568 1 } 6569 6570 6571 void 6572 GDtoLink(gd, fd) 6573 GopherDirObj *gd; 6574 int fd; 6575 { 6576 1 int i; 6577 1 6578 1 for (i=0; i< GDgetNumitems(gd); i++) { 6579 2 GStoLink(GDgetEntry(gd, i), fd, FALSE); 6580 2 } 6581 1 6582 1 } 6583 6584 /*** Search for a specific gopher item ***/ 6585 int 6586 GDSearch(gd, text) 6587 GopherDirObj *gd; 6588 char *text; /* Note first char is G0 type and is ignored*/ 6589 { 6590 1 int i; 6591 1 GopherObj *gs; 6592 1 int cplen; 6593 1 char *cp; 6594 1 6595 1 Debug("GDSearch: %s;\n",text); 6596 1 6597 1 if (gd == NULL) 6598 1 return(-1); 6599 1 6600 1 if (text == NULL) 6601 1 return(-1); 6602 1 6603 1 if ((int) strlen(text) <= 1) 6604 1 return(-1); 6605 1 6606 1 for (i=0; i< GDgetNumitems(gd); i++) { 6607 2 6608 2 gs = GDgetEntry(gd, i); 6609 2 cp = GSgetPath(gs); 6610 2 if (cp != NULL) { 6611 3 cplen = strlen(cp); 6612 3 6613 3 if (cplen >1 && strcmp(text+1, cp+1) == 0) { GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 12 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6614 4 Debugmsg("Matched\n"); 6615 4 return(i); 6616 4 } 6617 3 } 6618 2 } 6619 1 Debugmsg("GDsearch: No Match\n"); 6620 1 return(-1); 6621 1 } 6622 6623 /* 6624 * Delete an item in a gopher GD.. Do it in place... 6625 */ 6626 6627 GopherDirObj * 6628 GDdeleteGS(gd,j) 6629 GopherDirObj *gd; 6630 int j; /* Number of GS to delete */ 6631 { 6632 1 int i; 6633 1 6634 1 if (GDgetNumitems(gd) == j+1) { 6635 2 /* Last item in the directory */ 6636 2 GSinit(GDgetEntry(gd,j)); 6637 2 GDsetNumitems(gd, j); 6638 2 return(gd); 6639 2 } 6640 1 6641 1 /** Okay, now let's copy the items down, one by one.. **/ 6642 1 6643 1 for (i= j+1; i GDgetNumitems(gd)-1) 6650 1 GDsetCurrentItem(gd, GDgetCurrentItem(gd)-1); 6651 1 6652 1 return(gd); 6653 1 } 6654 6655 #ifdef VMS_SERVER 6656 X 6657 X /* 6658 X * Adds the "Date+Size" patch 6659 X */ 6660 X 6661 X void 6662 X GDaddDateNsize(gd) 6663 X GopherDirObj *gd; 6664 X { 6665 X int i; 6666 X GopherObj *ge; 6667 X 6668 X for (i=0; 6669 X i< GDgetNumitems(gd); 6670 X GSaddDateNsize(ge = GDgetEntry(gd, i++))); GDGOPHERDIR 22-SEP-1995 18:30:54 VAX C V3.2-044 Page 13 V1.0 26-MAY-1995 10:48:29 GDGOPHERDIR.C;2 (1) 6671 X } 6672 #endif Command Line ------------ CC/INCL=([-],[-.OBJECT])/DEFINE=(MULTINET=1,DEBUGGING,__VMS)/DEBUG/NOOPT/OBJ=[.VAX.DBG]/LIS=[.VAX.LIS] GDGOPHERDIR.C .