|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.