static void main_loop(void) { struct strbuf ctrl; struct strbuf data; int flags; int rc; int err; for (;;) { ctrl.maxlen = PKT_OCTL_LEN; ctrl.buf = (caddr_t)pkt_octl; data.maxlen = PKT_INPUT_LEN; data.buf = (caddr_t)pkt_input; /* Allow signals only while idle */ (void) sigprocmask(SIG_UNBLOCK, &sigmask, NULL); errno = 0; flags = 0; rc = mygetmsg(tunfd, &ctrl, &data, &flags); err = errno; /* * Block signals -- data structures must not change * while we're busy dispatching the client's request */ (void) sigprocmask(SIG_BLOCK, &sigmask, NULL); if (rc == -1) { if (err == EAGAIN || err == EINTR) continue; logerr("%s getmsg: %s", tunnam, mystrerror(err)); exit(1); } if (rc > 0) logwarn("%s returned truncated data", tunnam); else handle_input(pkt_octl, ctrl.len, pkt_input, data.len); } }
void search_given(char *given, search *mysearch) { struct stat info; stack *temp_stk; /*a temp var to work with history stack */ Node *temp_node; /* a temp var to work with hsitory stack node */ char *full_path; /* temp string of full path */ errno = 0; /*get the file info */ if (stat(given, &info) == -1) { perror(given); if (mysearch->client_fd > 0) send_err_line(mysearch, "%s: %s", given, mystrerror(errno)); return; } /* if it directory */ if (S_ISDIR(info.st_mode)) { /* get the full path */ full_path=scan_dir_name(given); if (full_path==NULL) return; /* * if -d is set to 0, do not process directory */ if (mysearch->max_dir_depth == 0) { fprintf(stderr, "%s is detected to exceed the search limit %d\n", full_path, mysearch->max_dir_depth); if (mysearch->client_fd > 0) send_err_line(mysearch, "%s is detected to exceed the search limit %d", full_path, mysearch->max_dir_depth); free(full_path); return; } else { /*allocate space to a history stack*/ if ((temp_stk = malloc(sizeof(stack))) == NULL) { perror("malloc():"); free(full_path); return; } else { /* initialize the stack and push it on stacks*/ temp_stk->mysearch = mysearch; stack_init(temp_stk); /* make a node */ if ((temp_node = make_node(full_path, 1, temp_stk)) == NULL) { free(full_path); free(temp_stk); return; } /*push the root node to the stack and kick it off*/ stack_push(temp_stk, temp_node, NULL); walk_to_next(temp_node); } } return; } else { search_file(given, mysearch, NULL); } /* search it as a file*/ return; }
/*ARGSUSED*/ void * fcal_leds_thread(void *args) { led_dtls_t *dtls = g_led_dtls; int c, v; int err = 0; int events = 0; int fd_bkplane; i2c_port_t port; int lastVal = I2C_IOCTL_INIT; int ws; int mask; /* * generate a mask for presence and fault status bits */ mask = 0; for (c = 0; c < dtls->n_disks; c++) { mask |= dtls->presence[c]; mask |= dtls->faults[c]; } /* * enter poll loop */ for (;;) { /* * see if a LED-test timer has expired */ for (c = 0; c < dtls->n_disks; c++) { if (dtls->led_test_end[c] > 0) { if (!dtls->polling) { /* poll thread failure, end led-test */ dtls->led_test_end[c] = 0; } else if ((events & FCAL_EV_POLL) != 0) { dtls->led_test_end[c]--; } if (dtls->led_test_end[c] == 0) { /* * clear blue and amber leds */ end_led_test(dtls, c); /* treat any status as a change */ lastVal = I2C_IOCTL_INIT; } } } fd_bkplane = open(dtls->fcal_status, O_RDONLY); if (fd_bkplane < 0) { SYSLOG(LOG_ERR, EM_CANT_OPEN, dtls->fcal_status); err = errno; break; } port.value = 0; /* * the direction and dir_mask fields are ignored, * so one can only guess at their possible use */ port.direction = DIR_INPUT; port.dir_mask = (uint8_t)mask; c = ioctl(fd_bkplane, I2C_GET_PORT, &port); if (c < 0) { err = errno; (void) close(fd_bkplane); if (lastVal != I2C_IOCTL_FAIL) { SYSLOG(LOG_ERR, EM_I2C_GET_PORT, mystrerror(err)); lastVal = I2C_IOCTL_FAIL; events |= FCAL_EV_CONFIG; } } else { (void) close(fd_bkplane); ws = port.value & mask; } if ((c == 0) && (ws != lastVal)) { events |= FCAL_EV_CONFIG; lastVal = ws; for (c = 0; c < dtls->n_disks; c++) { /* * first get the value of the relevant * presence bit (as 0 or 1) */ v = ((lastVal & dtls->presence[c]) != 0); /* hold previous presence value */ ws = dtls->disk_detected[c]; /* * the disk is present if the backplane * status bit for this disk is equal to the * configured assert_presence value */ dtls->disk_detected[c] = (v == dtls->assert_presence); /* * Don't add disk-unit node here for * newly arrived disks. While the led * test is running (and beyond) * libdevinfo is locked out and we * can't get port or target info. */ if ((!ws) && dtls->disk_detected[c]) { /* * disk has just come on-line */ start_led_test(dtls, c); } /* * clear leds and ready status * for disks which have been removed */ if (ws && (!dtls->disk_detected[c])) { clr_led(c, FCAL_REMOK_LED, dtls); clr_led(c, FCAL_FAULT_LED, dtls); clr_led(c, FCAL_READY_LED, dtls); dtls->disk_ready[c] = NO_MINORS; dtls->disk_prev[c] = NO_MINORS; v = update_picl(dtls, c); /* * set or clear retry flag */ dtls->picl_retry[c] = (v == EAGAIN); } /* * for present disks which are not doing a * led test, adjust fault LED */ if ((dtls->led_test_end[c] != 0) || (!dtls->disk_detected[c])) continue; v = ((lastVal & dtls->faults[c]) != 0); if (v == dtls->assert_fault) set_led(c, FCAL_FAULT_LED, dtls); else clr_led(c, FCAL_FAULT_LED, dtls); } } /* * For detected disks whose status has changed, choose between * ready and ok to remove. * libdevinfo can be locked out for the entire duration of a * disk spin-up. So it is best not to seek this info while * a led-test is in progress. Otherwise the leds can be stuck * on for about 40 seconds. * Note that chk_minors() returns 0 unless a status change * has occurred. */ if (!is_led_test(dtls) && chk_minors(dtls) != 0) { events = FCAL_EV_CONFIG; for (c = 0; c < dtls->n_disks; c++) { if (!dtls->disk_detected[c]) continue; /* * When disk_ready changes, disk_prev is set * to its previous value. This allows the * direction of the last transistion to be * determined. */ if ((dtls->disk_prev[c] == HAS_MINORS) && (dtls->disk_ready[c] == NO_MINORS)) { clr_led(c, FCAL_READY_LED, dtls); set_led(c, FCAL_REMOK_LED, dtls); } else { set_led(c, FCAL_READY_LED, dtls); clr_led(c, FCAL_REMOK_LED, dtls); } } } /* * Update PICL (disk-unit) for newly attached disks * ** see note in header file for significance * of disk_prev and disk_ready flags. */ for (c = 0; c < dtls->n_disks; c++) { if ((dtls->disk_prev[c] == NO_MINORS) && (dtls->disk_ready[c] == HAS_MINORS)) { dtls->disk_prev[c] = HAS_MINORS; v = update_picl(dtls, c); /* * set or clear retry flag */ dtls->picl_retry[c] = (v == EAGAIN); } } if ((events & FCAL_EV_CONFIG) != 0) { /* * set fast polling */ dtls->fast_poll_end = dtls->relax_time_ticks; } /* * if updating a led failed (e.g. I2C busy), try again */ if (dtls->led_retry) retry_led(dtls); events = wait_a_while(); /* * when picl is recycled, wait_a_while sleeps until the * init routine has been called again. * This is the moment when dtls may have become stale. */ if (dtls != g_led_dtls) { dtls = g_led_dtls; lastVal = I2C_IOCTL_INIT; /* * re-generate the presence and fault status mask * in case the .conf file has changed */ mask = 0; for (c = 0; c < dtls->n_disks; c++) { mask |= dtls->presence[c]; mask |= dtls->faults[c]; } } /* * count down relaxation time counter if a poll event */ if ((events & FCAL_EV_POLL) != 0) { if (dtls->fast_poll_end > 0) dtls->fast_poll_end--; } /* * if updating PICL needs retrying, try it now */ for (c = 0; c < dtls->n_disks; c++) { if (dtls->picl_retry[c]) { v = update_picl(dtls, c); dtls->picl_retry[c] = (v == EAGAIN); } } } return ((void *)err); }
void vsyslog(int pri, char *fmt, va_list ap) { extern int errno; register int cnt; register char *p; time_t now; int fd, saved_errno; char tbuf[2048], fmt_cpy[1024], *stdp; saved_errno = errno; /* see if we should just throw out this message */ if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) return; if (LogFile < 0 || !connected) openlog(LogTag, LogStat | LOG_NDELAY, 0); /* set default facility if none specified */ if ((pri & LOG_FACMASK) == 0) pri |= LogFacility; /* build the message */ (void)time(&now); (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); for (p = tbuf; *p; ++p); if (LogStat & LOG_PERROR) stdp = p; if (LogTag) { (void)strcpy(p, LogTag); for (; *p; ++p); } if (LogStat & LOG_PID) { (void)sprintf(p, "[%d]", getpid() ); for (; *p; ++p); } if (LogTag) { *p++ = ':'; *p++ = ' '; } /* substitute error message for %m */ { register char ch, *t1, *t2; for (t1 = fmt_cpy; ch = *fmt; ++fmt) if (ch == '%' && fmt[1] == 'm') { ++fmt; for (t2 = mystrerror(saved_errno); *t1 = *t2++; ++t1); } else *t1++ = ch; *t1 = '\0'; } (void)vsprintf(p, fmt_cpy, ap); cnt = strlen(tbuf); /* output to stderr if requested */ if (LogStat & LOG_PERROR) { write(2, tbuf,cnt); write(2,"\r\n",2); } /* output the message to the local logger */ if (send(LogFile, tbuf, cnt, 0) >= 0 || !(LogStat&LOG_CONS)) return; }
/* * Dispatch a message from the tunnel driver. It could be an actual * PPPoE message or just an event notification. */ static void handle_input(uint32_t *ctrlbuf, int ctrllen, uint32_t *databuf, int datalen) { poep_t *poep = (poep_t *)databuf; union ppptun_name ptn; int retv; struct strbuf ctrl; struct strbuf data; void *srvp; boolean_t launch; struct ppptun_control *ptc; if (ctrllen != sizeof (*ptc)) { logdbg("bogus %d byte control message from driver", ctrllen); return; } ptc = (struct ppptun_control *)ctrlbuf; /* Switch out on event notifications. */ switch (ptc->ptc_action) { case PTCA_TEST: logdbg("test reply for discriminator %X", ptc->ptc_discrim); return; case PTCA_CONTROL: break; case PTCA_DISCONNECT: logdbg("session %d disconnected on %s; send PADT", ptc->ptc_rsessid, ptc->ptc_name); poep = poe_mkheader(pkt_output, POECODE_PADT, ptc->ptc_rsessid); ptc->ptc_action = PTCA_CONTROL; ctrl.len = sizeof (*ptc); ctrl.buf = (caddr_t)ptc; data.len = poe_length(poep) + sizeof (*poep); data.buf = (caddr_t)poep; if (putmsg(tunfd, &ctrl, &data, 0) < 0) { logerr("putmsg PADT: %s", mystrerror(errno)); } else { output_packets++; } return; case PTCA_UNPLUMB: logdbg("%s unplumbed", ptc->ptc_name); return; default: logdbg("unexpected code %d from driver", ptc->ptc_action); return; } /* Only PPPoE control messages get here. */ input_packets++; if (datalen < sizeof (*poep)) { logdbg("incomplete PPPoE message from %s/%s", ehost(&ptc->ptc_address), ptc->ptc_name); return; } /* Server handles only PADI and PADR; all others are ignored. */ if (poep->poep_code == POECODE_PADI) { padi_packets++; } else if (poep->poep_code == POECODE_PADR) { padr_packets++; } else { loginfo("unexpected %s from %s", poe_codename(poep->poep_code), ehost(&ptc->ptc_address)); return; } logdbg("Recv from %s/%s: %s", ehost(&ptc->ptc_address), ptc->ptc_name, poe_codename(poep->poep_code)); /* Parse out service and formulate template reply. */ retv = locate_service(poep, datalen, ptc->ptc_name, &ptc->ptc_address, pkt_output, &srvp); /* Continue formulating reply */ launch = B_FALSE; if (retv != 1) { /* Ignore initiation if we don't offer a service. */ if (retv <= 0 && poep->poep_code == POECODE_PADI) { logdbg("no services; no reply"); return; } if (retv == 0) (void) poe_add_str((poep_t *)pkt_output, POETT_NAMERR, "No such service."); } else { /* Exactly one service chosen; if it's PADR, then we start. */ if (poep->poep_code == POECODE_PADR) { launch = B_TRUE; } } poep = (poep_t *)pkt_output; /* Select control interface for output. */ (void) strncpy(ptn.ptn_name, ptc->ptc_name, sizeof (ptn.ptn_name)); if (strioctl(tunfd, PPPTUN_SCTL, &ptn, sizeof (ptn), 0) < 0) { logerr("PPPTUN_SCTL %s: %s", ptn.ptn_name, mystrerror(errno)); return; } /* Launch the PPP service */ if (launch && launch_service(tunfd, poep, srvp, ptc)) sessions_started++; /* Send the reply. */ ctrl.len = sizeof (*ptc); ctrl.buf = (caddr_t)ptc; data.len = poe_length(poep) + sizeof (*poep); data.buf = (caddr_t)poep; if (putmsg(tunfd, &ctrl, &data, 0) < 0) { logerr("putmsg %s: %s", ptc->ptc_name, mystrerror(errno)); } else { output_packets++; logdbg("Send to %s/%s: %s", ehost(&ptc->ptc_address), ptc->ptc_name, poe_codename(poep->poep_code)); } }