|
|
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.