📄 laps.c
字号:
break; case LBV_STA_C_RELEASED: break; case LBV_STA_C_JOB_ABORT: /* * job aborted - if we asked for it, this is ok, * otherwise, it's an error */ if (abort) break; default: disconn_ps(sock); return(-1); break; } } disconn_ps(sock); return(0);}/* * i n t e r r u p t _ p r i n t e r * * This routine is called to send OOB interrupt message to printer. * * Returns: NULL on sccess * -1 on error * * Inputs: None * */interrupt_printer(){ FIELD8 type; /* * build a control message */ init_interrupt_msg_hdr(LMT_CONTROL); /* * insert the data description and data type */ type = LBV_CTL_INTERRUPT; insert_interrupt_block(LBT_CTL_CMD, &type, LBL_CTL_CMD); /* * send the interrupt message off */ if (flush_interrupt() != NULL) { disconn_ps (sock); return (-1); } return (NULL);}/* * s e t _ c o n d _ h a n d l e r * * This routine is called to define a condition record handler. * * Returns: None * * Inputs: * handler = Address of handler, * or NULL to cancel handler */set_cond_handler(handler)int (*handler)();{ cond_handler = handler;}/* * i n i t _ m s g _ h d r * * This routine is called to initialize the header of a new message to be * built. The message type is inserted, and the block count and length * fields are set to 0. * * Returns: NULL if success, * EOF if error flushing previous buffer contents * * Inputs: * msg_type Type of message being built */init_msg_hdr(msg_type)FIELD8 msg_type;{ struct msg_hdr *msg_ptr; /* * if there is data currently in the xmit buffer, send it */ if (xmit_len != 0) { if (flush_xmit() != NULL) return(EOF); } /* * init the message header */ msg_ptr = (struct msg_hdr *)xmit_buf; msg_ptr->msg_type = msg_type; msg_ptr->msg_blkcnt = 0; msg_ptr->msg_len = 0; xmit_ptr = xmit_buf + MSG_HDR_LEN; xmit_len = MSG_HDR_LEN; return(NULL);}/* * i n i t _ i n t e r r u p t _ m s g _ h d r * * This routine is called to initialize the interrupt header of a control * message to be built. The message type is inserted, and the block count and * length fields are set to 0. * * Returns: NULL * * Inputs: * msg_type Type of message being built */init_interrupt_msg_hdr(msg_type)FIELD8 msg_type;{ struct msg_hdr *msg_ptr; /* * init the message header */ msg_ptr = (struct msg_hdr *)intr_buf; msg_ptr->msg_type = msg_type; msg_ptr->msg_blkcnt = 0; msg_ptr->msg_len = 0; intr_ptr = intr_buf + MSG_HDR_LEN; intr_len = MSG_HDR_LEN; return(NULL);}/* * i n s e r t _ b l o c k * * This routine is called to build a block within a message. If there * is not enough room, it flushes the current message, and starts a new one. * It builds the block header, and copies the data supplied into the block. * * Returns: NULL on success * EOF on fatal error flushing the previous message * * Inputs: * type Type of block being built * data Data to be inserted into block * len Length of block to be built */insert_block(type, data, len)FIELD8 type;FIELD8 *data;FIELD16 len;{ struct msg_hdr *msg_ptr; struct blk_hdr *blk_ptr; msg_ptr = (struct msg_hdr *)xmit_buf; /* * check to see if the message being built is large enough to * hold the requested block - if not flush the current message * and start a new one of the same type */ if ((xmit_len + BLK_HDR_LEN + len) > sizeof(xmit_buf)) { if (xmit_len == 0) /* block is just too big */ { errno = EMSGSIZE; return(EOF); } if (init_msg_hdr(msg_ptr->msg_type) != NULL) return(EOF); } /* * build the block header */ blk_ptr = (struct blk_hdr *)xmit_ptr; blk_ptr->blk_type = type; INSERT16(blk_ptr->blk_len, len); /* * insert the block data */ bcopy(data, (xmit_ptr + BLK_HDR_LEN), len); /* * update the message header */ msg_ptr->msg_blkcnt +=1; msg_ptr->msg_len += (len + BLK_HDR_LEN); /* * update the transmit message pointer and length */ xmit_ptr += (len + BLK_HDR_LEN); xmit_len += (len + BLK_HDR_LEN); return(NULL);}/* * i n s e r t _ i n t e r r u p t _ b l o c k * * This routine is called to build a interrupt block within a message.If there * is not enough room, it flushes the current message, and starts a new one. * It builds the block header, and copies the data supplied into the block. * * Returns: NULL on success * EOF on fatal error flushing the previous message * * Inputs: * type Type of block being built * data Data to be inserted into block * len Length of block to be built */insert_interrupt_block(type, data, len)FIELD8 type;FIELD8 *data;FIELD16 len;{ struct msg_hdr *msg_ptr; struct blk_hdr *blk_ptr; msg_ptr = (struct msg_hdr *)intr_buf; /* * check to see if the message being built is large enough to * hold the requested block - if not flush the current message * and start a new one of the same type */ if ((intr_len + BLK_HDR_LEN + len) > sizeof(intr_buf)) { if (intr_len == 0) /* block is just too big */ { errno = EMSGSIZE; return(EOF); } if (init_interrupt_msg_hdr(msg_ptr->msg_type) != NULL) return(EOF); } /* * build the block header */ blk_ptr = (struct blk_hdr *)intr_ptr; blk_ptr->blk_type = type; INSERT16(blk_ptr->blk_len, len); /* * insert the block data */ bcopy(data, (intr_ptr + BLK_HDR_LEN), len); /* * update the message header */ msg_ptr->msg_blkcnt +=1; msg_ptr->msg_len += (len + BLK_HDR_LEN); /* * update the transmit message pointer and length */ intr_ptr += (len + BLK_HDR_LEN); intr_len += (len + BLK_HDR_LEN); return(NULL);}/* * f l u s h _ x m i t * * This routine is called to flush the transmit buffer and reset the * buffer pointer and length. * * Returns: NULL if success * EOF on error * * Inputs: none */flush_xmit(){ int status; status = write_ps(sock, xmit_buf, xmit_len); xmit_len = 0; if (status < 0) return(EOF); if (trace_flag) trace_xmit(xmit_buf); return(NULL);}/* * f l u s h _ i n t e r r u p t * * This routine is called to flush the interrupt buffer and reset the * buffer pointer and length. * * Returns: NULL if success * EOF on error * * Inputs: none */flush_interrupt(){ int status; status = interrupt_ps(sock, intr_buf, intr_len); intr_len = 0; if (status < 0) return(EOF); if (trace_flag) trace_xmit(intr_buf); return(NULL);}/* * r e a d _ m s g * * This routine is called to read in the next message. * * Returns Message type read * EOF on fatal error * * rcv_msg_type = message type received * * Inputs: None */FIELD8 read_msg(){ rcv_len = read_ps(sock, rcv_buf, sizeof(rcv_buf)); if (rcv_len <= 0) { rcv_len = 0; return(EOF); } if (trace_flag) trace_rcv(rcv_buf); rcv_msg_type = ((struct msg_hdr *)rcv_buf)->msg_type; rcv_ptr = rcv_buf + MSG_HDR_LEN; rcv_len -= MSG_HDR_LEN; if (rcv_len != ((struct msg_hdr *)rcv_buf)->msg_len) { rcv_len = 0; errno = EMSGSIZE; return(EOF); } return(rcv_msg_type);}/* * r e a d _ b l o c k * * This routine is called to get a block from a received message. * * Returns: Pointer to data portion of block read * NULL if no more blocks in current message * rcv_msg_type = message type * rcv_blk_type = block type * rcv_blk_len = length of block * * Inputs: None */FIELD8 *read_block(){ int status; struct msg_hdr *msg_ptr; struct blk_hdr *blk_ptr; FIELD16 *tmp; msg_ptr = (struct msg_hdr *)rcv_buf; /* * if no blocks in buffer */ if (rcv_len == 0) return(NULL); /* * get the address of the next block, and update the message pointers * and length */ blk_ptr = (struct blk_hdr *)rcv_ptr; /* * To correct unalinged access on MIPS, USE tmp, instead of * the following!!: * rcv_blk_len = *(FIELD16 *)(blk_ptr->blk_len); */ tmp = (FIELD16 *)(blk_ptr->blk_len); bcopy (tmp, &rcv_blk_len, 2); rcv_blk_type = blk_ptr->blk_type; msg_ptr->msg_blkcnt--; rcv_ptr += (rcv_blk_len + BLK_HDR_LEN); rcv_len -= (rcv_blk_len + BLK_HDR_LEN); if (msg_ptr->msg_blkcnt == 0) rcv_len = 0; return(((FIELD8 *)blk_ptr) + BLK_HDR_LEN);}/* * p r o c _ s t a t u s * * This function is called to process a status message. The contents * of each block is stored in the appropriate variable. * * Returns: NULL if success * EOF if error * * Inputs: NONE */proc_status(){ FIELD8 *ptr; FIELD8 mtype; int got_status = 0; int got_data = 0; /* * If laps_abort is set and connection is not accepted then * return error to disconnect the link. Actually server should * disconnect - BUT there is a discripancy in LAPS protocol!! * */ while (!got_status) { if (laps_abort && !con_accepted) return(EOF); while ((mtype = read_msg()) != LMT_STATUS) { if (mtype == (FIELD8)EOF) return(EOF); } got_data = 0; while ((ptr = read_block()) != NULL) { if (rcv_blk_type == LBT_STA_DATA) got_data = 1; if (decode_status_block(rcv_blk_type, ptr, rcv_blk_len) != NULL) return(EOF); } if (!got_data) got_status = 1; } return(NULL);}/* * p r o c _ a s y n c h * * This function is called to process any messages which arrived * asynchronously. These are expected to be condition records delivered * as status messages. * * Returns: NULL if success * EOF if error * * Inputs: NONE */proc_asynch(){ FIELD8 *ptr; FIELD8 mtype; int status; while (poll_msg(sock) != NULL) { mtype = read_msg(); if (mtype == (FIELD8)EOF) return(EOF); switch (mtype) { case LMT_STATUS: while ((ptr = read_block()) != NULL) { if (decode_status_block(rcv_blk_type, ptr, rcv_blk_len) != NULL) return(EOF); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -