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