예제 #1
0
파일: pppoed.c 프로젝트: alhazred/onarm
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);
	}
}
예제 #2
0
파일: search_given.c 프로젝트: ytz2/cs820
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;
}
예제 #3
0
/*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);
}
예제 #4
0
파일: SYSLOG.C 프로젝트: ErisBlastar/osfree
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;

}
예제 #5
0
파일: pppoed.c 프로젝트: alhazred/onarm
/*
 * 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));
	}
}