1: #ifndef lint
   2: static char *rcsid = "$Header: xnftp.c,v 2.0 85/11/21 07:22:51 jqj Exp $";
   3: #endif lint
   4: 
   5: /* $Log:	xnftp.c,v $
   6:  * Revision 2.0  85/11/21  07:22:51  jqj
   7:  * 4.3BSD standard release
   8:  *
   9:  * Revision 1.5  85/09/24  14:45:10  jqj
  10:  * fix bug in alarm() handling that caused aborts during large file transfers.
  11:  *
  12:  * Revision 1.4  85/09/17  07:49:47  jqj
  13:  * 4.3 changes.  Use more routines from CHlookup
  14:  *
  15:  * Revision 1.1  85/05/27  06:31:07  jqj
  16:  * Initial revision
  17:  *
  18:  */
  19: 
  20: #include <stdio.h>
  21: #include <sys/time.h>
  22: #include <sys/param.h>
  23: #include <sys/stat.h>
  24: #include <netns/ns.h>
  25: #include <netns/sp.h>
  26: #include "ftp_var.h"
  27: #include <xnscourier/CH.h>
  28: 
  29: CourierConnection *connected;
  30: Clearinghouse2_ObjectName hostobjname;
  31: Authentication1_Verifier verifier;
  32: 
  33: /* the following 3 items make up the current session */
  34: Filing4_Session session;    /* the current session */
  35: Clearinghouse2_ObjectName username;
  36: int continuetime;
  37: int remoteprocpending;
  38: Filing4_Handle wdHandle;    /* the current remote working dir */
  39: 
  40: static Filing4_ControlSequence nullControls = {0,0};
  41: static Filing4_ScopeSequence nullScope = {0,0};
  42: 
  43: /* global data used to communicate with BDT procedures
  44:  */
  45: extern GetAttributeSequences(),
  46:     listproc(), nlistproc(),
  47:     storeproc(), retrieveproc();
  48: static (*ProcEachSeq)();
  49: static long bytessent;
  50: static FILE *fout, *fin;
  51: 
  52: copyhandle(dest,src)
  53:     Filing4_Handle dest,src;
  54: {
  55:     if (dest == (Unspecified *) 0) {
  56:         fprintf(stderr,"Oops.  dest is null in copyhandle\n");
  57:         exit(1);
  58:     }
  59:     dest[0] = src[0];
  60:     dest[1] = src[1];
  61: }
  62: 
  63: StringToAttr(str, attr)
  64:     char *str;
  65:     Filing4_Attribute *attr;
  66: {
  67:     Unspecified buf[2049], *bp;
  68:     Cardinal len;
  69: 
  70:     bp = buf + sizeof_Cardinal(len);
  71:     len = externalize_String(&str, bp);
  72:     (void) externalize_Cardinal(&len, buf);
  73:     internalize_Clearinghouse2_Item(&(attr->value), buf);
  74:     return;
  75: }
  76: 
  77: char *
  78: AttrToString(attr)
  79:     Filing4_Attribute *attr;
  80: {
  81:     Unspecified buf[2049], *bp;
  82:     Cardinal len;
  83:     char *strval;
  84: 
  85:     externalize_Clearinghouse2_Item(&(attr->value), buf);
  86:     bp = buf;
  87:     bp += internalize_Cardinal(&len, bp);
  88:     bp += internalize_String(&strval, bp);
  89:     return(strval);
  90: }
  91: 
  92: UserToAttr(id, attr)
  93:     Clearinghouse2_Name id;
  94:     Filing4_Attribute *attr;
  95: {
  96:     Unspecified buf[2049], *bp;
  97:     Cardinal len;
  98: 
  99:     bp = buf + sizeof_Cardinal(len);
 100:     len = externalize_Clearinghouse2_Name(&id, bp);
 101:     (void) externalize_Cardinal(&len, buf);
 102:     internalize_Clearinghouse2_Item(&(attr->value), buf);
 103:     return;
 104: }
 105: 
 106: LongCardinalToAttr(val, attr)
 107:     LongCardinal val;
 108:     Filing4_Attribute *attr;
 109: {
 110:     Unspecified buf[3], *bp;
 111:     Cardinal len;
 112: 
 113:     bp = buf + sizeof_Cardinal(len);
 114:     len = externalize_LongCardinal(&val, bp);
 115:     (void) externalize_Cardinal(&len, buf);
 116:     internalize_Clearinghouse2_Item(&(attr->value), buf);
 117:     return;
 118: }
 119: 
 120: BooleanToAttr(val, attr)
 121:     int val;
 122:     Filing4_Attribute *attr;
 123: {
 124:     Boolean boolval;
 125:     Unspecified buf[3], *bp;
 126:     Cardinal len;
 127: 
 128:     boolval = (Boolean) val;
 129:     bp = buf + sizeof_Cardinal(len);
 130:     len = externalize_Boolean(&boolval, bp);
 131:     (void) externalize_Cardinal(&len, buf);
 132:     internalize_Clearinghouse2_Item(&(attr->value), buf);
 133:     return;
 134: }
 135: 
 136: int
 137: AttrToBoolean(attr)
 138:     Filing4_Attribute *attr;
 139: {
 140:     Unspecified buf[1];
 141:     Boolean result;
 142: 
 143:     (void) externalize_Unspecified(attr->value.sequence, buf);
 144:     (void) internalize_Boolean(&result, buf);
 145:     return(result);
 146: }
 147: 
 148: LongCardinal
 149: AttrToLongCardinal(attr)
 150:     Filing4_Attribute *attr;
 151: {
 152:     Unspecified buf[2];
 153:     LongCardinal result;
 154: 
 155:     (void) externalize_Unspecified(attr->value.sequence, buf);
 156:     (void) externalize_Unspecified((attr->value.sequence)+1, buf+1);
 157:     (void) internalize_LongCardinal(&result, buf);
 158:     return(result);
 159: }
 160: 
 161: 
 162: getfilehandle(filename, handle)
 163:     char *filename;
 164:     Filing4_Handle handle;
 165: {
 166:     Filing4_Attribute pathattr[1];
 167:     Filing4_AttributeSequence attrseq;
 168:     Filing4_OpenResults openresult;
 169: 
 170:     if (filename == (char *)0 || *filename == '\000') {
 171:         copyhandle(handle,wdHandle);
 172:         return;
 173:     }
 174:     attrseq.length = 1;
 175:     attrseq.sequence = pathattr;
 176:     pathattr[0].type = Filing4_pathname;
 177:     copyhandle(handle, Filing4_nullHandle);
 178:     if (*filename != '/') { /* relative pathname specified */
 179:         StringToAttr(filename, &pathattr[0]);
 180:         copyhandle(handle, wdHandle);
 181:     } else if (filename[1] == '\000') {
 182:         /* root specified */
 183:         attrseq.length = 0;
 184:     } else {    /* absolute pathname specified */
 185:         StringToAttr(filename+1, &pathattr[0]);
 186:     }
 187:     alarm(0);
 188:     openresult = Filing4_Open(connected, NULL, attrseq,
 189:                   handle, nullControls,
 190:                   session);
 191:     alarm(continuetime);
 192:     copyhandle(handle, openresult.file);
 193: }
 194: 
 195: freefilehandle(handle)
 196:     Filing4_Handle handle;
 197: {
 198:     if (handle[0] == Filing4_nullHandle[0] &&
 199:         handle[1] == Filing4_nullHandle[1])
 200:         return;     /* don't free nullHandle */
 201:     if (handle[0] == wdHandle[0] &&
 202:         handle[1] == wdHandle[1])
 203:         return;     /* don't free working directory */
 204:     alarm(0);
 205:     Filing4_Close(connected, NULL, handle, session);
 206:     alarm(continuetime);
 207: }
 208: 
 209: /*
 210:  * do a continue to make sure that the session doesn't time out.
 211:  * Note that this is usually called by an ALARM interrupt
 212:  */
 213: probe()
 214: {
 215:     Filing4_ContinueResults cresult;
 216: 
 217:     alarm(0);       /* cancel previous alarms */
 218:     cresult = Filing4_Continue(connected, NULL, session);
 219:     continuetime = cresult.continuance / 5; /* seconds */
 220:     alarm(continuetime);    /* reset for another 2 min. or so */
 221: }
 222: 
 223: CourierConnection *
 224: hookup(name)
 225:     char *name;
 226: {
 227:     register struct ns_addr *hostaddr;
 228:     extern struct ns_addr *getXNSaddr();
 229:     Clearinghouse2_ObjectName defaultobjname;
 230:     static char hnamebuf[128];
 231:     CourierConnection *cconn;
 232: 
 233:     CH_NameDefault(&defaultobjname);
 234:     hostobjname = CH_StringToName(name, &defaultobjname);
 235:     if ((hostaddr = CH_LookupAddrDN( hostobjname, 0, hnamebuf, 128))) {
 236:         /* should check here to be sure host is a file service */
 237:         hostaddr->x_port = htons(IDPPORT_COURIER); /* ?? */
 238:         cconn = CourierOpen(hostaddr);
 239:         /* reset objname to flush wildcards */
 240:         /* clear_Clearinghouse2_ThreePartName(&hostobjname); */
 241:         hostobjname = CH_StringToName(hnamebuf, &defaultobjname);
 242:         hostname = hnamebuf;
 243:         if (verbose)
 244:           printf("Connected to %s\n", hnamebuf);
 245:     } else {
 246:         printf("%s: unknown host\n", name);
 247:         cconn = (CourierConnection*)0;
 248:     }
 249:     return(cconn);
 250: }
 251: 
 252: 
 253: login(name,pwd)
 254:     char *pwd;
 255:     char *name;
 256: {
 257:     Authentication1_Credentials credentials;
 258:     Filing4_LogonResults logonresult;
 259: 
 260:     username = CH_StringToName(name,&hostobjname);
 261:     MakeSimpleCredsAndVerifier(&username,pwd,
 262:             &credentials, &verifier);
 263:     logonresult = Filing4_Logon(connected, NULL, hostobjname,
 264:                     credentials, verifier);
 265:     session = logonresult.session;
 266:     copyhandle(wdHandle, Filing4_nullHandle);
 267:     if (verbose)
 268:       printf("User %s:%s:%s logged on\n", username.object,
 269:          username.domain, username.organization);
 270:     alarm(0);
 271:     signal(SIGALRM, probe);
 272:     probe();
 273: }
 274: 
 275: logout()
 276: {
 277:     signal(SIGALRM, SIG_IGN);
 278:     Filing4_Logoff(connected, NULL, session);
 279:     clear_Filing4_Session(&session);
 280:     copyhandle(wdHandle, Filing4_nullHandle);
 281: }
 282: 
 283: domakedir(dest)
 284:     char *dest;
 285: {
 286:     sendrequest("MKDIR", "-", dest);
 287: }
 288: 
 289: doremovedir(src)
 290:     char *src;
 291: {
 292:     dodelete(src);
 293: }
 294: 
 295: dostore(src, dest)
 296:     char *src, *dest;
 297: {
 298:     sendrequest("STOR", src, dest);
 299: }
 300: 
 301: doappend(src, dest)
 302:     char *src, *dest;
 303: {
 304:     NYI();
 305: }
 306: 
 307: dorename(src, dest)
 308:     char *src, *dest;
 309: {
 310:     NYI();
 311: }
 312: 
 313: recvrequest(cmd, local, remote, mode)
 314:     char *cmd, *local, *remote, *mode;
 315: {
 316:     FILE *popen();
 317:     int (*closefunc)(), pclose(), fclose();
 318:     struct timeval start, stop;
 319:     Filing4_Handle remotehandle; /* note: an array */
 320:     Filing4_AttributeTypeSequence typeseq;
 321:     Filing4_AttributeType tsvals[10];
 322: 
 323:     closefunc = NULL;
 324:     fout = stdout;
 325:     typeseq.length = 0;  typeseq.sequence = tsvals;
 326:     if (strcmp(local, "-") && *local != '|')
 327:         if (access(local, 2) < 0) {
 328:             char *dir = rindex(local, '/');
 329:             /* get a good error message */
 330:             if (dir != NULL) *dir = '\0';
 331:             if (access(dir ? local : ".", 2) < 0) {
 332:                 perror(local);
 333:                 goto bad;
 334:             }
 335:             if (dir != NULL) *dir = '/';
 336:         }
 337:     if (strcmp(local, "-") == 0)
 338:         fout = stdout;
 339:     else if (*local == '|') {
 340:         fout = popen(local + 1, "w");
 341:         if (fout == NULL) {
 342:             perror(local + 1);
 343:             goto bad;
 344:         }
 345:         closefunc = pclose;
 346:     } else {
 347:         fout = fopen(local, mode);
 348:         if (fout == NULL) {
 349:             perror(local);
 350:             goto bad;
 351:         }
 352:         closefunc = fclose;
 353:     }
 354:     bytessent = 0;
 355:     gettimeofday(&start, (struct timezone *)0);
 356:     getfilehandle(remote, remotehandle);
 357:     alarm(0);
 358:     if (strcmp(cmd,"NLST") == 0) {
 359:         typeseq.length = 1;
 360:         typeseq.sequence[0] = Filing4_pathname;
 361:         ProcEachSeq = nlistproc;
 362:         Filing4_List(connected, GetAttributeSequences, remotehandle,
 363:                  typeseq, nullScope,
 364:                  BulkData1_immediateSink, session);
 365:     }
 366:     else if (strcmp(cmd,"LIST") == 0) {
 367:         typeseq.length = 5;
 368:         typeseq.sequence[0] = Filing4_name;
 369:         typeseq.sequence[1] = Filing4_dataSize;
 370:         typeseq.sequence[2] = Filing4_isDirectory;
 371:         typeseq.sequence[3] = Filing4_isTemporary;
 372:         typeseq.sequence[4] = Filing4_type;
 373:         ProcEachSeq = listproc;
 374:         Filing4_List(connected, GetAttributeSequences, remotehandle,
 375:                  typeseq, nullScope,
 376:                  BulkData1_immediateSink, session);
 377:     }
 378:     else if (strcmp(cmd,"RETR") == 0) {
 379:         Filing4_Retrieve(connected, retrieveproc, remotehandle,
 380:                  BulkData1_immediateSink, session);
 381:     }
 382:     else printf("unrecognized command %s\n",cmd);
 383:     alarm(continuetime);
 384:     gettimeofday(&stop, (struct timezone *)0);
 385:     freefilehandle(remotehandle);
 386:     if (bytessent > 0 && verbose)
 387:         ptransfer("received", bytessent, &start, &stop);
 388:  bad:
 389:     if (closefunc != NULL && fout != NULL)
 390:         (*closefunc)(fout);
 391:     fout = NULL;
 392: }
 393: 
 394: 
 395: sendrequest(cmd, local, remote)
 396:     char *cmd, *local, *remote;
 397: {
 398:     FILE *popen();
 399:     int (*closefunc)(), pclose(), fclose();
 400:     struct stat st;
 401:     struct timeval start, stop;
 402:     Filing4_StoreResults storeresults;
 403:     Filing4_CreateResults createresults;
 404:     Filing4_Handle remotehandle;
 405:     Filing4_AttributeSequence attrseq;
 406:     Filing4_Attribute attrvals[5];
 407: 
 408:     closefunc = NULL;
 409:     if (strcmp(local, "-") == 0) {
 410:         fin = stdin;
 411:         closefunc = NULL;
 412:     } else if (*local == '|') {
 413:         fin = popen(local + 1, "r");
 414:         if (fin == NULL) {
 415:             perror(local + 1);
 416:             goto bad;
 417:         }
 418:         closefunc = pclose;
 419:     } else {
 420:         fin = fopen(local, "r");
 421:         if (fin == NULL) {
 422:             perror(local);
 423:             goto bad;
 424:         }
 425:         closefunc = fclose;
 426:         if (fstat(fileno(fin), &st) < 0 ||
 427:             (st.st_mode&S_IFMT) != S_IFREG) {
 428:             fprintf(stderr, "%s: not a plain file.", local);
 429:             goto bad;
 430:         }
 431:     }
 432:     if (remote) {
 433:         char *dir = rindex(remote,'/');
 434:         if (dir != NULL) {
 435:             *dir = '\000';
 436:             getfilehandle(remote, remotehandle);
 437:             *dir = '/';
 438:             remote = dir+1;
 439:         } else {
 440:             getfilehandle("", remotehandle);
 441:         }
 442:     } else {
 443:         printf("No remote name specified\n");
 444:         return;
 445:     }
 446:     bytessent = 0;
 447:     gettimeofday(&start, (struct timezone *)0);
 448:     alarm(0);
 449:     if (strcmp(cmd,"STOR") == 0) {
 450:         attrseq.length = 2;
 451:         attrseq.sequence = attrvals;
 452:         attrvals[0].type = Filing4_name;
 453:         StringToAttr(remote, &attrvals[0]);
 454:         attrvals[1].type = Filing4_type;
 455:         if (typevalue == TYPE_A)
 456:           LongCardinalToAttr(Filing4_tText, &attrvals[1]);
 457:         else
 458:           LongCardinalToAttr(Filing4_tUnspecified, &attrvals[1]);
 459:         storeresults = Filing4_Store(connected, storeproc,
 460:                          remotehandle, attrseq,
 461:                          nullControls,
 462:                          BulkData1_immediateSource,
 463:                          session);
 464:         alarm(continuetime);
 465:         freefilehandle(storeresults.file);
 466:     }
 467:     else if (strcmp(cmd,"MKDIR") == 0) {
 468:         attrseq.length = 3;
 469:         attrseq.sequence = attrvals;
 470:         attrvals[0].type = Filing4_name;
 471:         StringToAttr(remote, &attrvals[0]);
 472:         attrvals[1].type = Filing4_isDirectory;
 473:         BooleanToAttr(1, &attrvals[1]);
 474:         attrvals[2].type = Filing4_type;
 475:         LongCardinalToAttr(Filing4_tDirectory, &attrvals[2]);
 476:         createresults = Filing4_Create(connected, NULL,
 477:                            remotehandle, attrseq,
 478:                            nullControls, session);
 479:         alarm(continuetime);
 480:         freefilehandle(createresults.file);
 481:     }
 482:     else {
 483:         printf("unrecognized command %s\n",cmd);
 484:         alarm(continuetime);
 485:     }
 486:     gettimeofday(&stop, (struct timezone *)0);
 487:     freefilehandle(remotehandle);
 488:     if (bytessent > 0 && verbose)
 489:         ptransfer("sent", bytessent, &start, &stop);
 490: bad:
 491:     if (closefunc != NULL && fin != NULL)
 492:         (*closefunc)(fin);
 493:     fin = NULL;
 494: }
 495: 
 496: 
 497: 
 498: docd(dest)
 499:     char *dest;
 500: {
 501:     Filing4_AttributeSequence attrseq;
 502:     Filing4_AttributeTypeSequence typeseq;
 503:     Filing4_AttributeType cdattrs[1];
 504:     Filing4_GetAttributesResults garesult;
 505:     Filing4_Handle remotehandle, temphandle;
 506:     char trydest[100];
 507:     int i;
 508: 
 509:     if (dest == (char*)NULL || *dest == '\0') {
 510:         trydest[0] = '/'; /* assume absolute pathname */
 511:         strcpy(trydest+1,username.object);
 512:         getfilehandle(trydest, remotehandle);
 513:     }
 514:     else
 515:         getfilehandle(dest, remotehandle);
 516:     typeseq.length = 1; typeseq.sequence = cdattrs;
 517:     cdattrs[0] = Filing4_isDirectory;
 518:     alarm(0);
 519:     garesult = Filing4_GetAttributes(connected, NULL, remotehandle,
 520:                      typeseq, session);
 521:     alarm(continuetime);
 522:     for (i = 0; i < garesult.attributes.length; i++) {
 523:         if (garesult.attributes.sequence[i].type == Filing4_isDirectory
 524:             && AttrToBoolean(&(garesult.attributes.sequence[i]))) {
 525:             copyhandle(temphandle, wdHandle);
 526:             copyhandle(wdHandle, remotehandle); /* change dir */
 527:             if (verbose) dopwd();
 528:             freefilehandle(temphandle); /* free old wdHandle */
 529:             return;
 530:         }
 531:     }
 532:     printf("%s is not a directory\n", dest);
 533:     freefilehandle(remotehandle);
 534: }
 535: 
 536: dopwd()
 537: {
 538:     Filing4_AttributeSequence attrseq;
 539:     Filing4_AttributeTypeSequence typeseq;
 540:     Filing4_AttributeType pwdattrs[1];
 541:     Filing4_GetAttributesResults garesult;
 542: 
 543:     if (wdHandle[0] == 0 && wdHandle[1] == 0) {
 544:         printf("Remote working directory:  /\n");
 545:         return;
 546:     }
 547:     typeseq.length = 1; typeseq.sequence = pwdattrs;
 548:     pwdattrs[0] = Filing4_pathname;
 549:     alarm(0);
 550:     garesult = Filing4_GetAttributes(connected, NULL, wdHandle, typeseq,
 551:                      session);
 552:     alarm(continuetime);
 553:     if (garesult.attributes.length > 0 &&
 554:         garesult.attributes.sequence[0].type == Filing4_pathname)
 555:         printf("Remote working directory:  /%s\n",
 556:                AttrToString(&(garesult.attributes.sequence[0])));
 557:     else printf("Remote working directory not set\n");
 558:     clear_Filing4_GetAttributesResults(&garesult);
 559: }
 560: 
 561: dodelete(src)
 562:     char *src;
 563: {
 564:     Filing4_Handle remotehandle;
 565:     Filing4_AttributeSequence attrseq;
 566:     Filing4_AttributeTypeSequence typeseq;
 567:     Filing4_AttributeType delattrs[1];
 568:     Filing4_GetAttributesResults garesult;
 569: 
 570:     typeseq.length = 1; typeseq.sequence = delattrs;
 571:     delattrs[0] = Filing4_isDirectory;
 572:     getfilehandle(src, remotehandle);
 573:     garesult = Filing4_GetAttributes(connected, NULL, remotehandle,
 574:                      typeseq, session);
 575:     if (garesult.attributes.length > 0 &&
 576:         garesult.attributes.sequence[0].type == Filing4_isDirectory &&
 577:         AttrToBoolean(&(garesult.attributes.sequence[0]))) {
 578:             if (!confirm("Delete directory", src)) return;
 579:     }
 580: 
 581:     clear_Filing4_GetAttributesResults(&garesult);
 582:     alarm(0);
 583:     Filing4_Delete(connected, NULL, remotehandle, session);
 584:     alarm(continuetime);
 585: }
 586: 
 587: NYI()
 588: {
 589:     printf("Not yet implemented\n");
 590: }
 591: 
 592: 
 593: ptransfer(direction, bytes, t0, t1)
 594:     char *direction;
 595:     long bytes;
 596:     struct timeval *t0, *t1;
 597: {
 598:     struct timeval td;
 599:     long ms;
 600:     float bs;
 601: 
 602:     tvsub(&td, t1, t0);
 603:     ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
 604: #define nz(x)   ((x) == 0 ? 1 : (x))
 605:     bs = ((1000. * (float) bytes) / (float) nz(ms));
 606:     printf("\n%ld bytes %s in %d.%02d seconds (%.2g Kbytes/s)\n",
 607:         bytes, direction, td.tv_sec, td.tv_usec / 10000, bs / 1024.);
 608: }
 609: 
 610: tvadd(tsum, t0)
 611:     struct timeval *tsum, *t0;
 612: {
 613: 
 614:     tsum->tv_sec += t0->tv_sec;
 615:     tsum->tv_usec += t0->tv_usec;
 616:     if (tsum->tv_usec > 1000000)
 617:         tsum->tv_sec++, tsum->tv_usec -= 1000000;
 618: }
 619: 
 620: tvsub(tdiff, t1, t0)
 621:     struct timeval *tdiff, *t1, *t0;
 622: {
 623: 
 624:     tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
 625:     tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
 626:     if (tdiff->tv_usec < 0)
 627:         tdiff->tv_sec--, tdiff->tv_usec += 1000000;
 628: }
 629: 
 630: nlistproc(attr)
 631:     Filing4_AttributeSequence attr;
 632: {
 633:     int i;
 634:     char *thisname;
 635:     Filing4_AttributeType t;
 636: 
 637:     for (i = 0; i < attr.length; i++) {
 638:         t = attr.sequence[i].type;
 639:         if (t == Filing4_pathname) fputc('/', fout);
 640:         if (t == Filing4_name ||
 641:             t == Filing4_pathname) {
 642:             thisname = AttrToString(&attr.sequence[i]);
 643:             fputs(thisname, fout);
 644:             fputc('\n', fout);
 645:             clear_String(&thisname);
 646:             return;
 647:         }
 648:     }
 649: }
 650: 
 651: 
 652: listproc(attr)
 653:     Filing4_AttributeSequence attr;
 654: {
 655:     int i;
 656:     char *thisname = "";
 657:     Boolean istemp = 0;
 658:     Boolean isdir = 0;
 659:     LongCardinal thistype = 0;
 660:     LongCardinal thissize = 0;
 661:     Filing4_AttributeType t;
 662:     char *filetypestr;
 663:     char filetypebuf[20];
 664: 
 665:     for (i = 0; i < attr.length; i++) {
 666:         t = attr.sequence[i].type;
 667:         if (t == Filing4_name ||
 668:             t == Filing4_pathname)
 669:             thisname = AttrToString(&attr.sequence[i]);
 670:         else if (t == Filing4_isDirectory)
 671:             isdir = AttrToBoolean(&attr.sequence[i]);
 672:         else if (t == Filing4_isTemporary)
 673:             istemp = AttrToBoolean(&attr.sequence[i]);
 674:         else if (t == Filing4_type)
 675:             thistype = AttrToLongCardinal(&attr.sequence[i]);
 676:         else if (t == Filing4_dataSize)
 677:             thissize = AttrToLongCardinal(&attr.sequence[i]);
 678:     }
 679: 
 680:     if (thistype == Filing4_tDirectory)
 681:         filetypestr = "(dir.)";
 682:     else if (thistype == Filing4_tText)
 683:         filetypestr = "(text)";
 684:     else if (thistype == Filing4_tSerialized)
 685:         filetypestr = "(ser.)";
 686:     else if (thistype == 4353)
 687:         filetypestr = "(Star)";
 688:     else if (thistype != Filing4_tUnspecified) {
 689:         sprintf(filetypebuf, "(%ld)", thistype);
 690:         filetypestr = filetypebuf;
 691:     }
 692:     else    filetypestr = "";
 693:     fprintf(fout, "%c%c%-6s%7ld %s\n",
 694:         isdir?'D':' ', istemp?'T':' ',
 695:         filetypestr, thissize, thisname);
 696:     clear_String(&thisname);
 697: }
 698: 
 699: #define MAXPACKS 20
 700: static
 701: GetAttributeSequences(conn)
 702:     CourierConnection *conn;
 703: {
 704:     int count, i;
 705:     Unspecified buffer[MAXWORDS*MAXPACKS], *bp, *bufend;
 706:     Filing4_StreamOfAttributeSequence attrs;
 707: 
 708:     bufend = buffer;
 709:     bp = buffer+((MAXWORDS-1)*MAXPACKS);    /* end of available space */
 710:     while ((count = BDTread(conn, (char*)bufend,
 711:                 MAXWORDS*sizeof(Unspecified))) > 0) {
 712:         bufend += count/sizeof(Unspecified);
 713:         bytessent += count;
 714:         if (bufend > bp) {
 715:             fprintf(stderr,"BDT read too big to fit\n");
 716:             BDTabort(conn);
 717:             /* should clear out stuff here if we knew how much */
 718:         }
 719:     }
 720:     bp = buffer;
 721:     while (bp < bufend) {
 722:         bp += internalize_Filing4_StreamOfAttributeSequence(&attrs,bp);
 723:         if (0 == (int) attrs.designator) {
 724:            for (i=0; i < attrs.nextSegment_case.segment.length; i++) {
 725:             (*ProcEachSeq)(
 726:                 attrs.nextSegment_case.segment.sequence[i]);
 727:            }
 728:            free(attrs.nextSegment_case.segment.sequence);
 729:         } else {
 730:            for (i = 0; i < attrs.lastSegment_case.length; i++) {
 731:             (*ProcEachSeq)(
 732:                 attrs.lastSegment_case.sequence[i]);
 733:            }
 734:            free(attrs.lastSegment_case.sequence);
 735:            return;
 736:         }
 737:     }
 738: }
 739: 
 740: int
 741: getBDTch(conn,bpp)
 742:     CourierConnection *conn;
 743:     u_char **bpp;
 744: {
 745:     static u_char buffer[SPPMAXDATA];
 746:     static int count;
 747: 
 748:     if (*bpp == NULL) {*bpp = buffer; count = 0;}
 749:     if (*bpp >= buffer+count) {
 750:         count=BDTread(conn,buffer,sizeof(buffer));
 751:         *bpp = buffer;
 752:     }
 753:     if (count <= 0) return(EOF);
 754:     else return(*((*bpp)++));
 755: 
 756: }
 757: 
 758: retrieveproc(conn)
 759:     CourierConnection *conn;
 760: {
 761:     int count, ocount, ch, hashbytes;
 762:     char buffer[SPPMAXDATA];
 763:     int charset, charset16;
 764:     char *bp;
 765: 
 766:     switch (typevalue) {
 767:     default:
 768:         fprintf(stderr,"We don't support type %s.  Using binary\n",
 769:             typename);
 770:     case TYPE_I:
 771:     case TYPE_L:
 772:         errno = ocount = 0;
 773:         fflush(fout);
 774:         while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) {
 775:             if ((ocount = write(fileno(fout),buffer,count)) < 0) {
 776:                 perror("write");
 777:                 BDTabort(conn);
 778:                 break;
 779:             }
 780:             bytessent += count;
 781:             if (hash) {
 782:                 putchar('#');
 783:                 fflush(stdout);
 784:             }
 785:         }
 786:         if (count < 0) perror("netin");
 787:         break;
 788: 
 789:     case TYPE_A:
 790:         charset = 0; charset16 = 0; bp = NULL;
 791:         hashbytes = 0;
 792:         while ((ch = getBDTch(conn,&bp)) != EOF) {
 793:             if (ch == '\377') {
 794:                 ch = getBDTch(conn,&bp);
 795:                 if (ch == '\377') charset16 = 1;
 796:                 else charset = ch;
 797:                 continue;
 798:             }
 799:             if (charset16) {
 800:                 charset = ch;
 801:                 ch = getBDTch(conn,&bp);
 802:             }
 803:             switch (charset) {
 804:             case 0: /* normal character set -- minimal xlation */
 805:                 if (ch == '\r') {
 806:                     ch = '\n';
 807:                     while (hash && bytessent >= hashbytes){
 808:                         putchar('#');
 809:                         fflush(stdout);
 810:                         hashbytes += sizeof(buffer);
 811:                     }
 812:                 }
 813:                 else if (ch == ','+0200) ch = '_';
 814:                 /* more mapping here */
 815:                 putc(ch,fout);
 816:                 bytessent++;
 817:                 break;
 818:             default:
 819:                 break; /* ignore */
 820:             }
 821:         }
 822:         if (hash) {
 823:             while (bytessent < hashbytes) {
 824:                 putchar('#');
 825:                 hashbytes += sizeof(buffer);
 826:             }
 827:             putchar('\n');
 828:             fflush(stdout);
 829:         }
 830:         /* if (count < 0) perror("netin"); */
 831:         break;
 832:     }
 833: }
 834: 
 835: storeproc(conn)
 836:     CourierConnection *conn;
 837: {
 838:     int count, ocount;
 839:     u_char buffer[SPPMAXDATA];
 840:     u_char *bp;
 841: 
 842:     errno = ocount = 0;
 843:     clearerr(fin);
 844:     switch (typevalue) {
 845:     default:
 846:         fprintf(stderr,"We don't support type %s.  Using binary\n",
 847:             typename);
 848:     case TYPE_I:
 849:     case TYPE_L:
 850:         while ((count = fread(buffer,sizeof(char),SPPMAXDATA,fin)) > 0
 851:                && (ocount = BDTwrite(conn, buffer, count)) > 0) {
 852:             bytessent += count;
 853:             if (hash) {
 854:                 putchar('#');
 855:                 fflush(stdout);
 856:             }
 857:         }
 858:         break;
 859:     case TYPE_A:
 860:         while ((count = fread(buffer,sizeof(char),SPPMAXDATA,fin))
 861:                > 0) {
 862:             ocount = count;
 863:             for (bp = buffer; count > 0; count--, bp++) {
 864:                 if (*bp == '\n') *bp = '\r';
 865:                 else if (*bp == '_') *bp = ','+0200;
 866:                 /* more translations here */
 867:             }
 868:             if ((ocount = BDTwrite(conn, buffer, ocount)) <= 0)
 869:                 break;
 870:             bytessent += ocount;
 871:             if (hash) {
 872:                 putchar('#');
 873:                 fflush(stdout);
 874:             }
 875:         }
 876:         break;
 877:     }
 878:     if (ocount < 0) {
 879:         BDTabort(conn);
 880:         perror("netout");
 881:     }
 882:     else if (ferror(fin)) {
 883:         BDTabort(conn);
 884:         perror("fread");
 885:     }
 886:     else
 887:         BDTclosewrite(conn);
 888: }

Defined functions

AttrToBoolean defined in line 136; used 4 times
AttrToLongCardinal defined in line 148; used 2 times
AttrToString defined in line 77; used 3 times
BooleanToAttr defined in line 120; used 1 times
GetAttributeSequences defined in line 700; used 3 times
LongCardinalToAttr defined in line 106; used 3 times
NYI defined in line 587; used 2 times
StringToAttr defined in line 63; used 4 times
UserToAttr defined in line 92; never used
copyhandle defined in line 52; used 8 times
doappend defined in line 301; never used
docd defined in line 498; used 1 times
dodelete defined in line 561; used 3 times
domakedir defined in line 283; used 1 times
dopwd defined in line 536; used 2 times
doremovedir defined in line 289; used 1 times
dorename defined in line 307; used 1 times
dostore defined in line 295; never used
freefilehandle defined in line 195; used 6 times
getBDTch defined in line 740; used 3 times
getfilehandle defined in line 162; used 6 times
hookup defined in line 223; used 2 times
listproc defined in line 652; used 2 times
login defined in line 253; used 2 times
logout defined in line 275; used 1 times
nlistproc defined in line 630; used 2 times
probe defined in line 213; used 4 times
ptransfer defined in line 593; used 2 times
recvrequest defined in line 313; used 5 times
retrieveproc defined in line 758; used 2 times
sendrequest defined in line 395; used 5 times
storeproc defined in line 835; used 2 times
tvadd defined in line 610; never used
tvsub defined in line 620; used 1 times

Defined variables

bytessent defined in line 49; used 13 times
continuetime defined in line 36; used 11 times
rcsid defined in line 2; never used
remoteprocpending defined in line 37; never used

Defined macros

MAXPACKS defined in line 699; used 2 times
nz defined in line 604; used 1 times
Last modified: 1986-03-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3004
Valid CSS Valid XHTML 1.0 Strict