12 int notifyf(void*, char*);
13 int readupto(uchar*, int);
14 int receive(int, uchar);
20 main(int argc, char **argv)
34 fprint(2, "usage: xmr filename\n");
37 fd = open("/dev/consctl", OWRITE);
39 write(fd, "rawon", 5);
40 fd = create(argv[0], ORDWR, 0666);
42 perror("xmr: create");
50 * keep receiving till the other side gives up
53 for(seqno = 1; ; seqno++){
54 if(receive(fd, seqno) == -1)
58 fprint(2, "xmr: received %ld bytes\n", bytes);
68 if(write(1, &c, 1) != 1){
69 fprint(2, "xmr: hungup\n");
75 readupto(uchar *a, int len)
80 for(sofar = 0; sofar < len; sofar += n){
81 n = read(0, a, len-sofar);
86 if(*a == Eot || *a == Cancel)
95 receive(int fd, uchar seqno)
104 for(have = 0, tries = 0;; tries++){
106 fprint(dfd, "have == %d\n", have);
108 fprint(2, "xmr: timed out\n");
114 /* try to gather up a block */
116 n = readupto(&buf[have], 132-have);
125 fprint(2, "xmr: transfer aborted by sender\n");
133 for(p = buf, sum = 0; p < &buf[128+3]; p++)
136 /* If invalid block, resynchronize */
137 if(buf[0] != Soh || buf[2] != (255-buf[1]) || sum != buf[131]){
139 fprint(dfd, "resync %2.2ux %d %d %ux %ux\n", buf[0],
140 buf[1], buf[2], sum, buf[131]);
141 write(dfd, (char*)buf+3, 128);
144 p = memchr(buf+1, Soh, 131);
147 memmove(buf, p, have);
153 /* it's probably a real block, so dump it if there's an error */
156 /* if this is the last block, ack */
157 if(buf[1] == seqno-1){
160 }else if(buf[1] == seqno){
162 fprint(dfd, "Ack\n");
164 if(write(fd, buf+3, 128) != 128){
165 fprint(2, "xmr: abort, error writing file\n");
176 notifyf(void *a, char *msg)
179 if(strcmp(msg, "alarm") == 0)