⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpsflash.c

📁 gpsd, a popular GPS daemon.
💻 C
📖 第 1 页 / 共 2 页
字号:
	while ((ch = getopt(argc, argv, "f:l:nVv:")) != -1)		switch (ch) {		case 'f':			fname = optarg;			fflag = true;			break;		case 'l':			lname = optarg;			lflag = true;			break;		case 'n':			nflag = true;			break;		case 'v':			verbosity = atoi(optarg);			break;		case 'V':			(void)fprintf(stderr, "SVN ID: $Id: gpsflash.c 4471 2007-12-08 08:02:57Z ckuethe $ \n");			exit(0);		default:			usage();			exit(0);			/* NOTREACHED */		}	argc -= optind;	argv += optind;	/* there is exactly one required argument, a tty device */	if (argc == 1) 	    port = argv[0];	else {	    usage();	    exit(0);	}	if (!nflag && 	    (((warning = getenv("I_READ_THE_WARNING")) == NULL) ||	     (strcmp(warning, "why oh why didn't i take the blue pill")!=0))){	    printf("\nThis program rewrites your receiver's flash ROM.\n");	    printf("If done improperly this will permanently ruin your\n");	    printf("receiver. We insist you read the gpsflash manpage\n");	    printf("before you break something.\n\n");	    nflag = true;	}	if (!nflag) {	    /* make sure we have meaningful flags */	    if (!fflag || fname == NULL) {		usage();		return 1;	    }	}	/* Open the serial port, blocking is OK */	if((pfd = open(port, O_RDWR | O_NOCTTY , 0600)) == -1) {		gpsd_report(LOG_ERROR, "open(%s)\n", port);		return 1;	}	/* try to get an identification string out of the firmware */	gpstype = NULL;	for (gp = types; *gp; gp++) {	    gpstype = *gp;	    gpsd_report(LOG_PROG, "probing for %s\n", gpstype->name);	    if (gpstype->probe(pfd, &version) == 0)		break;	}	if (gpstype == NULL || version == NULL) {	    gpsd_report(LOG_ERROR, "not a known GPS type\n");	    return 1;	}	/* OK, we have a known type */	gpsd_report(LOG_SHOUT, "GPS is %s, version '%s'.\n", gpstype->name, version);	if (lname == NULL)	    lname = (char *)gpstype->flashloader;	if (nflag) {	    gpsd_report(LOG_PROG, "probe finished.\n");	    return 0;	}	/* there may be a type-specific setup method */	memset(&term, 0, sizeof(term));	if(gpstype->port_setup(pfd, &term) == -1) {		gpsd_report(LOG_ERROR, "port_setup()\n");		return 1;	}	gpsd_report(LOG_PROG, "port set up...\n");	/* Open the loader file */	if((lfd = open(lname, O_RDONLY, 0444)) == -1) {	    gpsd_report(LOG_ERROR, "open(%s)\n", lname);	    return 1;	}	/* fstat() its file descriptor. Need the size, and avoid races */	if(fstat(lfd, &sb) == -1) {	    gpsd_report(LOG_ERROR, "fstat(%s)\n", lname);	    return 1;	}	/* minimal sanity check on loader size. also prevents bad malloc() */	ls = (size_t)sb.st_size;	if ((ls < gpstype->min_loader_size)||(ls > gpstype->max_loader_size)){	    gpsd_report(LOG_ERROR, "preposterous loader size: %d\n", ls);	    return 1;	}	gpsd_report(LOG_PROG, "passed sanity checks...\n");	/* malloc a loader buffer */	if ((loader = malloc(ls)) == NULL) {	    gpsd_report(LOG_ERROR, "malloc(%d)\n", ls);	    return 1;	}	if (read(lfd, loader, ls) != (ssize_t)ls) {	    (void)free(loader);	    gpsd_report(LOG_ERROR, "read(%d)\n", ls);	    return 1;	}	/* don't care if close fails - kernel will force close on exit() */	(void)close(lfd);	gpsd_report(LOG_PROG, "loader read in...\n");	/* Open the firmware image file */	/*@ -nullpass @*/	if((ffd = open(fname, O_RDONLY, 0444)) == -1) {	    (void)free(loader);	    gpsd_report(LOG_ERROR, "open(%s)]n", fname);	    return 1;	}	if(fstat(ffd, &sb) == -1) {	    (void)free(loader);	    gpsd_report(LOG_ERROR, "fstat(%s)\n", fname);	    return 1;	}	/* minimal sanity check on firmware size. also prevents bad malloc() */	fs = (size_t)sb.st_size;	if ((fs < gpstype->min_firmware_size) || (fs > gpstype->max_firmware_size)){	    (void)free(loader);	    gpsd_report(LOG_ERROR, "preposterous firmware size: %d\n", fs);	    return 1;	}	/* malloc an image buffer */	if ((firmware = malloc(fs+1)) == NULL) {	    (void)free(loader);	    gpsd_report(LOG_ERROR, "malloc(%u)\n", (unsigned)fs);	    return 1;	}	/* get the firmware */	if (read(ffd, firmware, fs) != (ssize_t)fs) {	    (void)free(loader);	    (void)free(firmware);	    gpsd_report(LOG_ERROR, "read(%u)\n", (unsigned)fs);	    return 1;	}	firmware[fs] = '\0';	/* don't care if close fails - kernel will force close on exit() */	(void)close(ffd);	gpsd_report(LOG_PROG, "firmware read in...\n");	/* did we just read some S-records? */	if (!((firmware[0] == 'S') && ((firmware[1] >= '0') && (firmware[1] <= '9')))){ /* srec? */	    (void)free(loader);	    (void)free(firmware);	    gpsd_report(LOG_ERROR, "%s: not an S-record file\n", fname);	    return 1;	}	if(gpstype->version_check(pfd, version, loader, ls, firmware, fs)==-1){		(void)free(loader);		(void)free(firmware);		gpsd_report(LOG_ERROR, "version_check()\n");		return 1;	}	/*	 * dlgps2.bin starts flashing when it sees valid srecords.	 * validate the entire image before we flash. shooting self	 * in foot is bad, mmmkay?	 */	gpsd_report(LOG_PROG, "validating firmware\n");	if (srec_check(firmware)){	    (void)free(loader);	    (void)free(firmware);	    gpsd_report(LOG_ERROR, "%s: corrupted firmware image\n", fname);	    return 1;	}	/*@ +nullpass @*/	gpsd_report(LOG_PROG, "firmware validated\n");	gpsd_report(LOG_PROG, "version checked...\n");	gpsd_report(LOG_PROG, "blocking signals...\n");	/* once we get here, we are uninterruptable. handle signals */	(void)sigemptyset(&sigset);	(void)sigaddset(&sigset, SIGINT);	(void)sigaddset(&sigset, SIGHUP);	(void)sigaddset(&sigset, SIGQUIT);	(void)sigaddset(&sigset, SIGTSTP);	(void)sigaddset(&sigset, SIGSTOP);	(void)sigaddset(&sigset, SIGKILL);	if(sigprocmask(SIG_BLOCK, &sigset, NULL) == -1) {		(void)free(loader);		(void)free(firmware);		gpsd_report(LOG_ERROR,"sigprocmask\n");		return 1;	}	/* send the command to begin the update */	if(gpstype->stage1_command!=NULL && (gpstype->stage1_command(pfd) == -1)) {		(void)free(loader);		(void)free(firmware);		gpsd_report(LOG_ERROR, "Stage 1 update command\n");		return 1;	}	gpsd_report(LOG_PROG, "sending loader...\n");	/* send the bootstrap/flash programmer */	if(gpstype->loader_send(pfd, &term, loader, ls) == -1) {		(void)free(loader);		(void)free(firmware);		gpsd_report(LOG_ERROR, "Loader send\n");		return 1;	}	(void)free(loader);	gpsd_report(LOG_PROG, "initializing firmware load...\n");	/* send any command needed to demarcate the two loads */	if(gpstype->stage2_command!=NULL && (gpstype->stage2_command(pfd) == -1)) {	    (void)free(firmware);	    gpsd_report(LOG_ERROR, "Stage 2 update command\n");	    return 1;	}	gpsd_report(LOG_PROG, "performing firmware load...\n");	/* and now, poke the actual firmware over */	if(gpstype->firmware_send(pfd, firmware, fs) == -1) {	    (void)free(firmware);	    gpsd_report(LOG_ERROR, "Firmware send\n");	    return 1;	}	(void)free(firmware);	gpsd_report(LOG_PROG, "finishing firmware load...\n");	/* send any command needed to finish the firmware load */	if(gpstype->stage3_command!=NULL && (gpstype->stage3_command(pfd) == -1)) {	    gpsd_report(LOG_ERROR, "Stage 3 update command\n");	    return 1;	}	gpsd_report(LOG_PROG, "unblocking signals...\n");	if(sigprocmask(SIG_UNBLOCK, &sigset, NULL) == -1) {		gpsd_report(LOG_ERROR,"sigprocmask\n");		return 1;	}	/* type-defined wrapup, take our tty to GPS's post-flash settings */	if(gpstype->port_wrapup(pfd, &term) == -1) {		gpsd_report(LOG_ERROR, "port_wrapup()\n");		return 1;	}	gpsd_report(LOG_PROG, "finished.\n");	/* return() from main(), to take advantage of SSP compilers */	return 0;}static boolsrec_check(const char *data){	int i, l, n, x, y, z;	char buf[85];	l = 0;	while(strlen(data)){		/* grab a line of firmware, ignore line endings */		memset(buf,0,85);		l++;		if(sscanf(data, "%80s", buf) == EOF){			gpsd_report(LOG_ERROR, "line %d read failed\n", l);			return true;		}		n = (int)strlen(buf);		if ((n < 1) || (n > 80)){			gpsd_report(LOG_ERROR, "firmware line %d invalid length %d\n", l, n);			return true;		}		/* advance to the next srecord */		data += n;		while((data[0] != 'S') && (data[0] != '\0'))			data++;		if (buf[0] != 'S'){			gpsd_report(LOG_INF, "%s\n", buf);			gpsd_report(LOG_ERROR, "firmware line %d doesn't begin with 'S'.\n", l);			return true;		}		x = hex2bin(buf+2);		y = (n - 4)/2;		if (x != y){			gpsd_report(LOG_INF, "buf: '%s'\n", buf);			gpsd_report(LOG_ERROR, "firmware line %d length error: %d != %d\n", l, x, y);			return true;		}		x = hex2bin(buf+n-2);		y = 0;		for(i = 2; i < n-2; i+=2){			z = hex2bin(buf+i);			y += z;		}		y &= 0xff; y ^= 0xff;		if (x != y){			gpsd_report(LOG_INF, "buf: '%s'\n", buf);			gpsd_report(LOG_ERROR, "firmware line %d checksum error: %x != %x\n", l, x, y);			return true;		}	}	return false;}

⌨️ 快捷键说明

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