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