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

📄 tty_clk_streams.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
字号:
/* tty_clk_STREAMS.c,v 3.1 1993/07/06 01:07:34 jbj Exp * Timestamp STREAMS module for SunOS 4.1 * * Copyright 1991, Nick Sayer * * Special thanks to Greg Onufer for his debug assists. * * Should be PUSHed directly on top of a serial I/O channel. * For any character in a user-designated set, adds a kernel * timestamp to that character. * * BUGS: * * Only so many characters can be timestamped. This number, however, * is adjustable. * * The null character ($00) cannot be timestamped. * * The M_DATA messages passed upstream will not be the same * size as when they arrive from downstream, even if no * timestamp character is in the message. This, however, * should not affect anything. * */#include "clk.h"#if NCLK > 0/* * How big should the messages we pass upstream be? */#define MESSAGE_SIZE 128#include <string.h>#include <sys/types.h>#include <sys/stream.h>#include <sys/param.h>#include <sys/time.h>#include <sys/kernel.h>#include <sys/user.h>#include <sys/errno.h>#include <sys/syslog.h>#include <sys/clkdefs.h>static struct module_info rminfo = { 0, "clk", 0, INFPSZ, 0, 0 };static struct module_info wminfo = { 0, "clk", 0, INFPSZ, 0, 0 };static int clkopen(), clkrput(), clkwput(), clkclose();static struct qinit rinit = { clkrput, NULL, clkopen, clkclose, NULL,	&rminfo, NULL };static struct qinit winit = { clkwput, NULL, NULL, NULL, NULL,	&wminfo, NULL };struct streamtab clkinfo = { &rinit, &winit, NULL, NULL };struct priv_data_type{  char in_use;  char string[CLK_MAXSTRSIZE];} priv_data[NCLK];char first_open=1;/* * God only knows why, but linking with strchr() fails * on my system, so here's a renamed copy. */u_char *str_chr(s,c)u_char *s;int c;{  while (*s)    if(*s++ == c)      return (s-1);  return NULL;}/*ARGSUSED*/static int clkopen(q, dev, flag, sflag)queue_t *q;dev_t dev;int flag;int sflag;{  int i;/* Damn it! We can't even have the global data struct properly   initialized! So we have a mark to tell us to init the global   data on the first open */  if (first_open)  {    first_open=0;    for(i=0;i<NCLK;i++)      priv_data[i].in_use=0;  }  for(i=0;i<NCLK;i++)    if(!priv_data[i].in_use)    {      priv_data[i].in_use++;      ((struct priv_data_type *) (q->q_ptr))=priv_data+i;      priv_data[i].string[0]=0;      return (0);    }  u.u_error = EBUSY;  return (OPENFAIL);}/*ARGSUSED*/static int clkclose(q, flag)queue_t *q;int flag;{  ((struct priv_data_type *) (q->q_ptr))->in_use=0;  return (0);}/* * Now the crux of the biscuit. * * If it's an M_DATA package, we take each character and pass * it to clkchar. */void clkchar();static int clkrput(q, mp)queue_t *q;mblk_t *mp;{  mblk_t *bp;  switch(mp->b_datap->db_type)  {    case M_DATA:      clkchar(0,q,2);      for(bp=mp; bp!=NULL; bp=bp->b_cont)      {	while(bp->b_rptr < bp->b_wptr)	  clkchar( ((u_char)*(bp->b_rptr++)) , q , 0 );      }      clkchar(0,q,1);      freemsg(mp);    break;    default:      putnext(q,mp);    break;  }}/* * If it's a matching M_IOCTL, handle it. */static int clkwput(q, mp)queue_t *q;mblk_t *mp;{  struct iocblk *iocp;  switch(mp->b_datap->db_type)  {    case M_IOCTL:      iocp=(struct iocblk*) mp->b_rptr;      if (iocp->ioc_cmd==CLK_SETSTR)      {        strncpy( ((struct priv_data_type *) (RD(q)->q_ptr))->string,	  (char *) mp->b_cont->b_rptr,CLK_MAXSTRSIZE);        /* make sure it's null terminated */	((struct priv_data_type *) (RD(q)->q_ptr))->string[CLK_MAXSTRSIZE-1]=0;	mp->b_datap->db_type = M_IOCACK;	qreply(q,mp);      }      else	putnext(q,mp);    break;    default:      putnext(q,mp);    break;  }}/* * Now clkchar. It takes a character, a queue pointer and an action * flag and depending on the flag either: * * 0 - adds the character to the current message. If there's a * timestamp to be done, do that too. If the message is less than * 8 chars from being full, link in a new one, and set it up for * the next call. * * 1 - sends the whole mess to Valhala. * * 2 - set things up. * * Yeah, it's an ugly hack. Complaints may be filed with /dev/null. */void clkchar(c,q,f)	register u_char c;	queue_t *q;	char f;{  static char error;  static mblk_t *message,*mp;  struct timeval tv;/* Get a timestamp ASAP! */  uniqtime(&tv);  switch(f)  {    case 1:      if (!error)        putnext(q,message);    break;    case 2:      mp=message= (mblk_t*) allocb(MESSAGE_SIZE,BPRI_LO);      error=(message==NULL);      if (error)	log(LOG_ERR,"clk: cannot allocate message - data lost");    break;    case 0:      if (error) /* If we had an error, forget it. */	return;      *mp->b_wptr++=c; /* Put the char away first.      /* If it's in the special string, append a struct timeval */      if (str_chr( ((struct priv_data_type *) (q->q_ptr))->string ,        c )!=NULL)      {	  int i;	  for (i=0;i<sizeof(struct timeval);i++)	    *mp->b_wptr++= *( ((char*)&tv) + i );      }      /* If we don't have space for a complete struct timeval, and a         char, it's time for a new mp block */      if (((mp->b_wptr-mp->b_rptr)+sizeof(struct timeval)+2)>MESSAGE_SIZE)      {	  mp->b_cont= (mblk_t*) allocb(MESSAGE_SIZE,BPRI_LO);	  error=(mp->b_cont==NULL);	  if (error)	  {	    log(LOG_ERR,"clk: cannot allocate message - data lost");	    freemsg(message);          }          mp=mp->b_cont;      }    break;  }}#endif

⌨️ 快捷键说明

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