|
|
1.1 root 1: #include <stddef.h>
2: #include <stdio.h>
3: #include <unistd.h>
4: #include "dist.h"
5:
6: #define MIN(A, B) ((A) < (B) ? (A) : (B))
7:
8: int
9: getline(char line[])
10: {
11: int i;
12:
13: i = 0;
14: do
15: if (read(0, line + i, 1) != 1)
16: return 0;
17: while (line[i++] != '\n' && i < MAXLINE - 1);
18: if (line[i - 1] != '\n')
19: return 0;
20: line[i] = 0;
21: return 1;
22: }
23:
24: long
25: fdcopy(int dst, int src, long size, unsigned long *crc)
26: {
27: char buf[4096];
28: long cc, total;
29: int aux;
30:
31: total = 0;
32: if (crc) {
33: crcinit(&aux);
34: *crc = 0;
35: }
36: while (total < size) {
37: if ((cc = read(src, buf, MIN(sizeof buf, size - total))) <= 0)
38: break;
39: if (crc)
40: *crc = crcincr((unsigned char *) buf, cc, *crc, &aux);
41: if (write(dst, buf, cc) != cc)
42: break;
43: total += cc;
44: }
45: return total;
46: }
47:
48: int
49: sendfile(int fd)
50: {
51: long len;
52: char mesg[MAXLINE];
53: unsigned long crc;
54:
55: /* size header */
56: len = lseek(fd, 0L, 2);
57: lseek(fd, 0L, 0);
58: sprintf(mesg, "file length=%ld\n", len);
59: write(1, mesg, strlen(mesg));
60:
61: /* body */
62: if (fdcopy(1, fd, len, &crc) != len) {
63: eprintf("sendfile fdcopy failure");
64: return 0;
65: }
66:
67: /* crc footer */
68: sprintf(mesg, "file crc=%lu\n", crc);
69: write(1, mesg, strlen(mesg));
70:
71: /* acknowledge */
72: if (!getline(mesg) || strcmp(mesg, "ok\n") != 0) {
73: eprintf("sendfile acknowledgement failure");
74: return 0;
75: }
76:
77: return 1;
78: }
79:
80: int
81: recvfile(int fd)
82: {
83: long len;
84: char mesg[MAXLINE];
85: unsigned long crc, trycrc;
86:
87: /* size header */
88: if (!getline(mesg) || sscanf(mesg, "file length=%ld\n", &len) != 1) {
89: eprintf("recvfile header munged");
90: return 0;
91: }
92:
93: /* body */
94: if (fdcopy(fd, 0, len, &crc) != len) {
95: eprintf("recvfile fdcopy failure");
96: return 0;
97: }
98:
99: /* crc footer */
100: if (!getline(mesg) || sscanf(mesg, "file crc=%lu\n", &trycrc) != 1) {
101: eprintf("recvfile footer munged");
102: return 0;
103: }
104: if (crc != trycrc) {
105: eprintf("recvfile crc failure");
106: return 0;
107: }
108:
109: /* acknowledge */
110: sprintf(mesg, "ok\n");
111: write(1, mesg, strlen(mesg));
112: return 1;
113: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.