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