irpsion5.c

来自「linux操作系统下的红外驱动的测试程序」· C语言 代码 · 共 688 行 · 第 1/2 页

C
688
字号
		       "file size changed: initial: %lu, actual: %d\n",		       s.st_size, cnt);	}	/* Check for close on the other side */	rc = read(fd,buf,buflen);	if (rc > 0) {		fprintf(stderr, "Strange: the other side responded.\n");		fprintf(stderr, "rc=%d, data:%s\n", rc, buf);		exit(1);	}	if (rc == 0) {		fprintf(stderr, "Received end of file.\n");	}	if (rc == -1) {		if (errno == EPERM) {			/* Strange error code to get in this case */			DEBUG(1, "Other side closed connection, OK\n");		} else {			perror("last read");			exit(1);		}	}	if (verbose) {		t = time(NULL);		if (t == t0) t++;	/* white lie for fast transfers */		printf("\r%79s\r","");	/* Cleanup the progress line */		printf("Sent %s, %d bytes in %d sec. %g KBytes/sec\n",		       filename, cnt, t - t0, cnt / 1000.0 / (t - t0));	}	close(fd);	return 0;}int handle_client(int cfd) {	int buflen;	char* buf;	int rc;	/* fields of file transfer header */	unsigned int fsize;	unsigned int fmode;	unsigned int fdate1;	unsigned int fdate2;	char* fname;	unsigned int fdate;	unsigned long long int fdatell;	FILE* f;	int cnt;	int t0, tx, t;	buflen = irttp_get_mtu(cfd);	DEBUG(1, "mtu=%d\n", buflen);	if (buflen != 2045 && buflen != 2044) {		fprintf(stderr, "Expecting mtu to be 2045, investigate!\n");	}	DEBUG(1, "Setting mtu to 2044\n");	buflen = 2044;	if (!(buf = malloc(buflen))) {		perror("malloc");		exit(1);	}	if (!(buf = malloc(buflen))) {		fprintf(stderr, "malloc buf failed\n");		exit(1);	}	/* Wait for the other side to send a header */	/* 	   Sample headers received:	   DATA 185	   FILE 55175 32 14689800 2691219200 Data	        size mode datehi  datelo     name	*/	/*	   This version only sends and receives files.	   It is possible to extend this to other data types the	   Psion can send and receive.	*/	rc = read(cfd, buf, buflen);	if (rc < 0) {		perror("1st read");		exit(1);	}	if (rc == 0) {		perror("1st read 0");		exit(1);	}	assert(rc < buflen);	buf[rc] = 0;	DEBUG(1, "%s\n", buf);	fsize = 0;	fdate = 0;	if (0 == strncmp(buf, "FILE ", 5)) {		cnt = 0; /* to be safe */		rc = sscanf(buf, "FILE %u %u %u %u %n", 			    &fsize, &fmode, &fdate1, &fdate2,			    &cnt);		if (!(rc == 4 || rc == 5)) {			/* grumble */			fprintf(stderr, "sscanf \"%s\" rc=%d\n", buf, rc);			exit(1);		}		assert(cnt < buflen);		fname = strdup(buf+cnt);		fdatell = ((unsigned long long int) fdate1 << 32) + fdate2;		fdate = ( fdatell - 62168263200000000ULL) / 1000000 ;				DEBUG(1, "filename: %s\n", fname);		DEBUG(1, "filesize: %d\n", fsize);		DEBUG(1, "Filemode: %d", fmode);		DEBUG(1, "%s", (fmode &  1 ? ", Readonly" : ""));		DEBUG(1, "%s", (fmode &  2 ? ", Hidden" : ""));		DEBUG(1, "%s", (fmode & 32 ? ", Modified" : ""));		DEBUG(1, "%s", (fmode & ~35 ? ", Unknown" : ""));		DEBUG(1, "\n");		DEBUG(1, "fdate1:   %u = 0x%x\n", fdate1, fdate1);		DEBUG(1, "fdate2:   %u = 0x%x\n", fdate2, fdate2);		DEBUG(1, "filedate: %Ld\n", fdatell);		DEBUG(1, "filedate: %d = %s", fdate, 		       asctime(gmtime((time_t*)&fdate)));		if (!(f = fopen(fname,"wb"))) {			perror(fname);			exit(1);		}	} else if (0 == strncmp(buf, "DATA ", 5)) {		rc = sscanf(buf, "DATA %d", &fsize);		if (rc != 1) {			fprintf(stderr, "sscanf rc=%d\n", rc);			exit(1);		}		fname = strdup("/tmp/psion5-data");		if (!(f = fopen(fname,"wb"))) {			perror(fname);			exit(1);		}	} else {		fprintf(stderr, "Unknown data type: %s\n", buf);		exit(1);	}	rc = write(cfd,"ACK Y",5);	if (rc != 5) {		perror("1st write");		fprintf(stderr,"1st write rc = %d\n", rc);		exit(1);	}				cnt = 0;	t0 = tx = t = time(NULL);	while (cnt < fsize) {		int wrc;		rc = read(cfd,buf,buflen);		if (rc < 0) {			perror("data read");			/* EPERM on disconnect ? */			exit(1);		}		if (rc == 0) {			perror("data read 0");			exit(1);		}		wrc = fwrite(buf,rc,1,f);		if (wrc != 1) {			perror("fwrite");			exit(1);		}		cnt += rc;		if (verbose) {			/* progress indication */			t = time(NULL);			if (t - t0 == 0 || cnt == 0 || tx == t)				/* avoid division errors */				/* only once per second */				continue;			tx = t;			printf("got %d/%u bytes=%g%% in %d sec,"			       " %g Kbytes/s, to go %i sec  \r", 			       cnt, fsize, 100.0 * cnt / fsize, t - t0,			       cnt / 1000.0 / (t - t0), 			       ( fsize - cnt ) * (t - t0) / cnt);			fflush(stdout);		}	}			if (cnt != fsize) {		printf("Warning: "		       "file size changed: initial: %u, actual: %d\n",		       fsize, cnt);	}	if (verbose) {		if (t == t0) t++;	/* white lie for fast transfers */		printf("\r%79s\r","");	/* Cleanup the progress line */		printf("Received %s, %d bytes in %d sec. %g KBytes/sec\n",		       fname, cnt, t - t0, cnt / 1000.0 / (t - t0));	}	rc = fclose(f);	if (rc != 0) {		perror("fclose");		exit(1);	}	if (fdate) {		struct utimbuf utb;		utb.actime = fdate;		utb.modtime = fdate;		rc = utime(fname,&utb);		if (rc != 0) {			perror(fname);		}	}	free(fname);	close(cfd);	return 0;}int receivefile(int mode){	/* 	   The Psion 5 tries the following connections:	   Epoc32:EikonIr:v1.0	IrDA:TinyTP:LsapSel	   IrDA:IrCOMM       	Parameters	   IrLPT              	IrDA:IrLMP:LsapSel	   connect on 2	   Warning: discovery reply after 101ms	*/	int addrlen = sizeof(struct sockaddr_irda);	int fd;	struct sockaddr_irda peer;	int cfd;        /* Create socket */	fd = socket(AF_IRDA, SOCK_STREAM, 0);	if (fd < 0) {		perror("socket");		exit(-1);        }	/* Bind local service */	peer.sir_family = AF_IRDA;	strcpy(peer.sir_name, "Epoc32:EikonIr:v1.0");	peer.sir_lsap_sel = LSAP_ANY;		if (bind(fd, (struct sockaddr*)&peer, sizeof(struct sockaddr_irda))) {			perror("bind");			return -1;	}	if (listen(fd, 2)) {		perror("listen");		return -1;	}	/* FIXME: allow more simultaneous clients */	for (;;) {		cfd = accept(fd, (struct sockaddr *) &peer, &addrlen);		if (cfd < 0) {			perror("accept");			return -1;		}		if (handle_client(cfd))			break;	       		if (mode == 1)			break;	}	/* sleep(1); */	close(fd);	return 0;}intmain(int argc, char* argv[]) {	char* argv0 = argv[0];	if (argc <= 1) {		fprintf(stderr, "Usage: %s [-S ms] [-D n] [-v] [-q] "				"[-s file] [-r] [-b]\n", argv0);		fprintf(stderr, "\t-s file\tSend file to the Psion\n");		fprintf(stderr, "\t-r\tReceive a file from the Psion\n");		fprintf(stderr, "\t-b\tReceive multiple files (batch mode)\n");		fprintf(stderr, "\t-v\tVerbose mode, progress indication\n");		fprintf(stderr, "\t-q\tquiet mode, no progress indication\n");		fprintf(stderr, "\t-S ms\tSet discovery slot timeout,");		fprintf(stderr, " standard 80ms, default 120ms\n");		fprintf(stderr, "\t-D n\tDebug level\n");		exit(1);	}		/* skip program name */	argv++; argc--;	for ( ; argc>0 && argv[0] ; argc-- , argv++) {		if (0 == strcmp(argv[0],"-s")) {			/* FIXME: sending multiple files does not			   work yet. We need to wait for the user			   to select receive again on the psion */			if (argv[1] && 0 == strcmp(argv[1],"--")) {				/* Allow the user to send ANY filename */				argv++; argv++;				for ( ; argv[1] ; argv++ , argc--) {					sendfile(argv[1]);				}			} else {				/* Send files upto next switch */				while (argv[1] && *argv[1] != '-') {					sendfile(argv[1]);					argv++; argc--;				}			}		} else if (argv[0] && 0 == strcmp(argv[0],"-D")) {			debug_level = atoi(argv[1]);			argv++; argc--;		} else if (argv[0] && 0 == strcmp(argv[0],"-S")) {			slot_timeout = atoi(argv[1]);			argv++; argc--;		} else if (argv[0] && 0 == strcmp(argv[0],"-r")) {			receivefile(1);		} else if (argv[0] && 0 == strcmp(argv[0],"-b")) {			receivefile(0);		} else if (argv[0] && 0 == strcmp(argv[0],"-v")) {			verbose = 1;		} else if (argv[0] && 0 == strcmp(argv[0],"-q")) {			verbose = 0;		} else {			fprintf(stderr,"Error: unknown switch %s\n", argv[0]);			fprintf(stderr,"Call without args for usage: %s\n", 				argv0);			exit(1);		}	}	return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?