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

📄 ntpdc.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 3 页
字号:
	else	    tvo = tvsout;		FD_SET(sockfd, &fds);	n = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);	if (n == -1) {		warning("select fails", "", "");		return -1;	}	if (n == 0) {		/*		 * Timed out.  Return what we have		 */		if (firstpkt) {			(void) fprintf(stderr,				       "%s: timed out, nothing received\n", currenthost);			return ERR_TIMEOUT;		} else {			(void) fprintf(stderr,				       "%s: timed out with incomplete data\n",				       currenthost);			if (debug) {				printf("Received sequence numbers");				for (n = 0; n <= MAXSEQ; n++)				    if (haveseq[n])					printf(" %d,", n);				if (lastseq != 999)				    printf(" last frame received\n");				else				    printf(" last frame not received\n");			}			return ERR_INCOMPLETE;		}	}	n = recv(sockfd, (char *)&rpkt, sizeof(rpkt), 0);	if (n == -1) {		warning("read", "", "");		return -1;	}	/*	 * Check for format errors.  Bug proofing.	 */	if (n < RESP_HEADER_SIZE) {		if (debug)		    printf("Short (%d byte) packet received\n", n);		goto again;	}	if (INFO_VERSION(rpkt.rm_vn_mode) > NTP_VERSION ||	    INFO_VERSION(rpkt.rm_vn_mode) < NTP_OLDVERSION) {		if (debug)		    printf("Packet received with version %d\n",			   INFO_VERSION(rpkt.rm_vn_mode));		goto again;	}	if (INFO_MODE(rpkt.rm_vn_mode) != MODE_PRIVATE) {		if (debug)		    printf("Packet received with mode %d\n",			   INFO_MODE(rpkt.rm_vn_mode));		goto again;	}	if (INFO_IS_AUTH(rpkt.auth_seq)) {		if (debug)		    printf("Encrypted packet received\n");		goto again;	}	if (!ISRESPONSE(rpkt.rm_vn_mode)) {		if (debug)		    printf("Received request packet, wanted response\n");		goto again;	}	if (INFO_MBZ(rpkt.mbz_itemsize) != 0) {		if (debug)		    printf("Received packet with nonzero MBZ field!\n");		goto again;	}	/*	 * Check implementation/request.  Could be old data getting to us.	 */	if (rpkt.implementation != implcode || rpkt.request != reqcode) {		if (debug)		    printf(			    "Received implementation/request of %d/%d, wanted %d/%d",			    rpkt.implementation, rpkt.request,			    implcode, reqcode);		goto again;	}	/*	 * Check the error code.  If non-zero, return it.	 */	if (INFO_ERR(rpkt.err_nitems) != INFO_OKAY) {		if (debug && ISMORE(rpkt.rm_vn_mode)) {			printf("Error code %d received on not-final packet\n",			       INFO_ERR(rpkt.err_nitems));		}		return (int)INFO_ERR(rpkt.err_nitems);	}	/*	 * Collect items and size.  Make sure they make sense.	 */	items = INFO_NITEMS(rpkt.err_nitems);	size = INFO_ITEMSIZE(rpkt.mbz_itemsize);	if (esize > size)		pad = esize - size;	else 		pad = 0;	if ((datasize = items*size) > (n-RESP_HEADER_SIZE)) {		if (debug)		    printf(			    "Received items %d, size %d (total %d), data in packet is %d\n",			    items, size, datasize, n-RESP_HEADER_SIZE);		goto again;	}	/*	 * If this isn't our first packet, make sure the size matches	 * the other ones.	 */	if (!firstpkt && esize != *rsize) {		if (debug)		    printf("Received itemsize %d, previous %d\n",			   size, *rsize);		goto again;	}	/*	 * If we've received this before, +toss it	 */	seq = INFO_SEQ(rpkt.auth_seq);	if (haveseq[seq]) {		if (debug)		    printf("Received duplicate sequence number %d\n", seq);		goto again;	}	haveseq[seq] = 1;	/*	 * If this is the last in the sequence, record that.	 */	if (!ISMORE(rpkt.rm_vn_mode)) {		if (lastseq != 999) {			printf("Received second end sequence packet\n");			goto again;		}		lastseq = seq;	}	/*	 * So far, so good.  Copy this data into the output array.	 */	if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) {		int offset = datap - pktdata;		growpktdata();	        *rdata = pktdata; /* might have been realloced ! */		datap = pktdata + offset;	}	/* 	 * We now move the pointer along according to size and number of	 * items.  This is so we can play nice with older implementations	 */	tmp_data = (char *)rpkt.data;	for(i = 0; i <items; i++){		memmove(datap, tmp_data, (unsigned)size);		tmp_data += size;		memset(datap + size, 0, pad);		datap += size + pad;	}	if (firstpkt) {		firstpkt = 0;		*rsize = size + pad;	}	*ritems += items;	/*	 * Finally, check the count of received packets.  If we've got them	 * all, return	 */	++numrecv;	if (numrecv <= lastseq)	    goto again;	return INFO_OKAY;}/* * sendrequest - format and send a request packet */static intsendrequest(	int implcode,	int reqcode,	int auth,	int qitems,	int qsize,	char *qdata	){	struct req_pkt qpkt;	int datasize;	memset((char *)&qpkt, 0, sizeof qpkt);	qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);	qpkt.implementation = (u_char)implcode;	qpkt.request = (u_char)reqcode;	datasize = qitems * qsize;	if (datasize != 0 && qdata != NULL) {		memmove((char *)qpkt.data, qdata, (unsigned)datasize);		qpkt.err_nitems = ERR_NITEMS(0, qitems);		qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);	} else {		qpkt.err_nitems = ERR_NITEMS(0, 0);		qpkt.mbz_itemsize = MBZ_ITEMSIZE(0);	}	if (!auth) {		qpkt.auth_seq = AUTH_SEQ(0, 0);		return sendpkt((char *)&qpkt, req_pkt_size);	} else {		l_fp ts;		int maclen = 0;		const char *pass = "\0";		struct req_pkt_tail *qpktail;		qpktail = (struct req_pkt_tail *)((char *)&qpkt + req_pkt_size		    + MAX_MAC_LEN - sizeof(struct req_pkt_tail));		if (info_auth_keyid == 0) {			if (((struct conf_peer *)qpkt.data)->keyid > 0)				info_auth_keyid = ((struct conf_peer *)qpkt.data)->keyid;			else {				maclen = getkeyid("Keyid: ");				if (maclen == 0) {					(void) fprintf(stderr,					    "Invalid key identifier\n");					return 1;				}				info_auth_keyid = maclen;			}		}		if (!authistrusted(info_auth_keyid)) {			pass = getpass("MD5 Password: ");			if (*pass == '\0') {				(void) fprintf(stderr,				    "Invalid password\n");				return (1);			}		}		authusekey(info_auth_keyid, info_auth_keytype, (const u_char *)pass);		authtrust(info_auth_keyid, 1);		qpkt.auth_seq = AUTH_SEQ(1, 0);		qpktail->keyid = htonl(info_auth_keyid);		get_systime(&ts);		L_ADD(&ts, &delay_time);		HTONL_FP(&ts, &qpktail->tstamp);		maclen = authencrypt(info_auth_keyid, (u_int32 *)&qpkt,		    req_pkt_size);		if (maclen == 0) {  			(void) fprintf(stderr, "Key not found\n");			return (1);		}		return sendpkt((char *)&qpkt, (int)(req_pkt_size + maclen));	}	/*NOTREACHED*/}/* * doquery - send a request and process the response */intdoquery(	int implcode,	int reqcode,	int auth,	int qitems,	int qsize,	char *qdata,	int *ritems,	int *rsize,	char **rdata, 	int quiet_mask,	int esize	){	int res;	char junk[512];	fd_set fds;	struct timeval tvzero;	/*	 * Check to make sure host is open	 */	if (!havehost) {		(void) fprintf(stderr, "***No host open, use `host' command\n");		return -1;	}	/*	 * Poll the socket and clear out any pending data	 */again:	do {		tvzero.tv_sec = tvzero.tv_usec = 0;		FD_ZERO(&fds);		FD_SET(sockfd, &fds);		res = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);		if (res == -1) {			warning("polling select", "", "");			return -1;		} else if (res > 0)		    (void) recv(sockfd, junk, sizeof junk, 0);	} while (res > 0);	/*	 * send a request	 */	res = sendrequest(implcode, reqcode, auth, qitems, qsize, qdata);	if (res != 0)	    return res;		/*	 * Get the response.  If we got a standard error, print a message	 */	res = getresponse(implcode, reqcode, ritems, rsize, rdata, esize);	/*	 * Try to be compatible with older implementations of ntpd.	 */	if (res == INFO_ERR_FMT && req_pkt_size != 48) {		int oldsize;		oldsize = req_pkt_size;		switch(req_pkt_size) {		case REQ_LEN_NOMAC:			req_pkt_size = 160;			break;		case 160:			req_pkt_size = 48;			break;		}		if (impl_ver == IMPL_XNTPD) {			fprintf(stderr,			    "***Warning changing to older implementation\n");			return INFO_ERR_IMPL;		}		fprintf(stderr,		    "***Warning changing the request packet size from %d to %d\n",		    oldsize, req_pkt_size);		goto again;	} 	/* log error message if not told to be quiet */ 	if ((res > 0) && (((1 << res) & quiet_mask) == 0)) {		switch(res) {		    case INFO_ERR_IMPL:			/* Give us a chance to try the older implementation. */			if (implcode == IMPL_XNTPD)				break;			(void) fprintf(stderr,				       "***Server implementation incompatable with our own\n");			break;		    case INFO_ERR_REQ:			(void) fprintf(stderr,				       "***Server doesn't implement this request\n");			break;		    case INFO_ERR_FMT:			(void) fprintf(stderr,				       "***Server reports a format error in the received packet (shouldn't happen)\n");			break;		    case INFO_ERR_NODATA:			(void) fprintf(stderr,				       "***Server reports data not found\n");			break;		    case INFO_ERR_AUTH:			(void) fprintf(stderr, "***Permission denied\n");			break;		    case ERR_TIMEOUT:			(void) fprintf(stderr, "***Request timed out\n");			break;		    case ERR_INCOMPLETE:			(void) fprintf(stderr,				       "***Response from server was incomplete\n");			break;		    default:			(void) fprintf(stderr,				       "***Server returns unknown error code %d\n", res);			break;		}	}	return res;}/* * getcmds - read commands from the standard input and execute them */static voidgetcmds(void){#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)	char *line;	for (;;) {		if ((line = readline(interactive?prompt:"")) == NULL) return;		if (*line) add_history(line);		docmd(line);		free(line);	}#else /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */	char line[MAXLINE];	for (;;) {		if (interactive) {#ifdef VMS	/* work around a problem with mixing stdout & stderr */			fputs("",stdout);#endif			(void) fputs(prompt, stderr);			(void) fflush(stderr);		}		if (fgets(line, sizeof line, stdin) == NULL)		    return;		docmd(line);	}#endif /* not HAVE_LIBREADLINE || HAVE_LIBEDIT */}#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler *//* * abortcmd - catch interrupts and abort the current command */static RETSIGTYPEabortcmd(	int sig	){	if (current_output == stdout)	    (void) fflush(stdout);	putc('\n', stderr);	(void) fflush(stderr);	if (jump) longjmp(interrupt_buf, 1);}#endif /* SYS_WINNT *//* * docmd - decode the command line and execute a command */static voiddocmd(	const char *cmdline	){	char *tokens[1+MAXARGS+2];	struct parse pcmd;	int ntok;	int i, ti;	int rval;	struct xcmd *xcmd;	ai_fam_templ = ai_fam_default;	/*	 * Tokenize the command line.  If nothing on it, return.	 */	tokenize(cmdline, tokens, &ntok);	if (ntok == 0)	    return;		/*	 * Find the appropriate command description.	 */	i = findcmd(tokens[0], builtins, opcmds, &xcmd);	if (i == 0) {		(void) fprintf(stderr, "***Command `%s' unknown\n",			       tokens[0]);		return;	} else if (i >= 2) {		(void) fprintf(stderr, "***Command `%s' ambiguous\n",			       tokens[0]);		return;	}		/*	 * Save the keyword, then walk through the arguments, interpreting	 * as we go.	 */	pcmd.keyword = tokens[0];	pcmd.nargs = 0;	ti = 1;	for (i = 0; i < MAXARGS && xcmd->arg[i] != NO;) {		if ((i+ti) >= ntok) {			if (!(xcmd->arg[i] & OPT)) {				printusage(xcmd, stderr);				return;			}			break;		}		if ((xcmd->arg[i] & OPT) && (*tokens[i+ti] == '>'))			break;		rval = getarg(tokens[i+ti], (int)xcmd->arg[i], &pcmd.argval[i]);		if (rval == -1) {			ti++;			continue;		}		if (rval == 0)			return;		pcmd.nargs++;		i++;	}	/* Any extra args are assumed to be "OPT|NTP_STR". */	for ( ; i < MAXARGS + MOREARGS;) {	     if ((i+ti) >= ntok)		  break;		rval = getarg(tokens[i+ti], (int)(OPT|NTP_STR), &pcmd.argval[i]);		if (rval == -1) {			ti++;			continue;		}		if (rval == 0)			return;		pcmd.nargs++;		i++;	}	i += ti;	if (i < ntok && *tokens[i] == '>') {		char *fname;		if (*(tokens[i]+1) != '\0')		    fname = tokens[i]+1;		else if ((i+1) < ntok)		    fname = tokens[i+1];		else {			(void) fprintf(stderr, "***No file for redirect\n");			return;		}		current_output = fopen(fname, "w");		if (current_output == NULL) {			(void) fprintf(stderr, "***Error opening %s: ", fname);			perror("");			return;		}	} else {		current_output = stdout;	}	if (interactive && setjmp(interrupt_buf)) {		return;	} else {		jump = 1;		(xcmd->handler)(&pcmd, current_output);		jump = 0;		if (current_output != stdout)			(void) fclose(current_output);		current_output = NULL;	}}/* * tokenize - turn a command line into tokens */static voidtokenize(	const char *line,	char **tokens,	int *ntok	){	register const char *cp;	register char *sp;	static char tspace[MAXLINE];	sp = tspace;	cp = line;	for (*ntok = 0; *ntok < MAXTOKENS; (*ntok)++) {		tokens[*ntok] = sp;		while (ISSPACE(*cp))		    cp++;		if (ISEOL(*cp))		    break;		do {			*sp++ = *cp++;		} while (!ISSPACE(*cp) && !ISEOL(*cp));		*sp++ = '\0';	}}/* * findcmd - find a command in a command description table */static intfindcmd(	register char *str,	struct xcmd *clist1,	struct xcmd *clist2,	struct xcmd **cmd	){	register struct xcmd *cl;	register int clen;	int nmatch;	struct xcmd *nearmatch = NULL;	struct xcmd *clist;	clen = strlen(str);	nmatch = 0;	if (clist1 != 0)	    clist = clist1;	else if (clist2 != 0)	    clist = clist2;	else	    return 0;    again:	for (cl = clist; cl->keyword != 0; cl++) {		/* do a first character check, for efficiency */		if (*str != *(cl->keyword))

⌨️ 快捷键说明

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