예제 #1
0
파일: ps2.c 프로젝트: sjrct/Frosk
static void ps2_command(uint port, uchar cmd, uchar * buf, int sz)
{
	int i;

	if (port) outb(PS2_CMND, 0xD4);

	do_assert(wait_write());
	outb(PS2_DATA, cmd);
	do_assert(wait_read());

	if (inb(PS2_DATA) != 0xFA) {
		assert(0);
	}

	if (buf != NULL) {
		for (i = 0; wait_read() && i < sz; i++) {
			buf[i] = inb(PS2_DATA);
		}
	}
}
예제 #2
0
파일: ps2.c 프로젝트: sjrct/Frosk
// device should be disabled
static void detect_device(uint port, uchar enable, uchar test, uchar mask)
{
	ps2_device * ps2d;
	uchar check = 0;
	ushort type = 0;

	if (get_config() & mask) {
		outb(PS2_CMND, enable);

		if (!(get_config() & mask)) {
			outb(PS2_CMND, test);
			do_assert(wait_read());

			if (!inb(PS2_DATA)) {
				ps2_command(port, 0xFF, &check, 1);

				if (check == 0xAA) {
					ps2_command(port, 0xF5, NULL, 0);
					ps2_command(port, 0xF2, (uchar *)(&type), 2);

					if (type == PS2_NO_DEVICE) {
						type = PS2_KB_NORMAL;
					}

					if (type == PS2_KB_NORMAL || type == PS2_KB_MF2) {
						ps2_devs[port] = create_stream(
								sizeof(unsigned),
								ps2_kb_enable,
								ps2_kb_disable,
								ps2_kb_read,
								NULL
						);

						ps2d = kalloc(sizeof(ps2_device));
						ps2d->type = type;
						ps2d->port = port;
						ps2_devs[port]->data = ps2d;

						reg_dev(DEVICE_INPUT, ps2_devs[port]->hndl);
						enable_device(ps2_devs[port]);
					} else {
						ps2_devs[port] = NULL; //TODO: implement
					}

					kprintf("PS/2 Device %x detected.\n", type);
				}
			} else {
				outb(PS2_CMND, enable - 1);
			}
		}
	}
}
예제 #3
0
static ssize_t mailstream_low_ssl_read(mailstream_low * s,
				       void * buf, size_t count)
{
  struct mailstream_ssl_data * ssl_data;
  int r;

  ssl_data = (struct mailstream_ssl_data *) s->data;
  
  if (mailstream_cancel_cancelled(ssl_data->cancel))
    return -1;
  
  while (1) {
    int ssl_r;
    
    r = SSL_read(ssl_data->ssl_conn, buf, count);
    if (r > 0)
      return r;
    
    ssl_r = SSL_get_error(ssl_data->ssl_conn, r);
    switch (ssl_r) {
    case SSL_ERROR_NONE:
      return r;
      
    case SSL_ERROR_ZERO_RETURN:
      return r;
      
    case SSL_ERROR_WANT_READ:
      r = wait_read(s);
      if (r < 0)
        return r;
      break;
      
    default:
      return -1;
    }
  }
}
예제 #4
0
static ssize_t mailstream_low_ssl_read(mailstream_low * s,
				       void * buf, size_t count)
{
  struct mailstream_ssl_data * ssl_data;
  int r;

  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (mailstream_cancel_cancelled(ssl_data->cancel))
    return -1;
  
  while (1) {
    r = gnutls_record_recv(ssl_data->session, buf, count);
    if (r > 0)
      return r;
    
    switch (r) {
    case 0: /* closed connection */
      return -1;
    
    case GNUTLS_E_REHANDSHAKE:
      do {
         r = gnutls_handshake(ssl_data->session); 
      } while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED);
      break; /* re-receive */
    case GNUTLS_E_AGAIN:
    case GNUTLS_E_INTERRUPTED:
      r = wait_read(s);
      if (r < 0)
        return r;
      break;
      
    default:
      return -1;
    }
  }
}
예제 #5
0
파일: ps2.c 프로젝트: sjrct/Frosk
void detect_ps2(void)
{
	// disable ps/2 devices
	outb(PS2_CMND, 0xAD);
	outb(PS2_CMND, 0xA7);

	flush_output();

	// disable interrupts and translation
	chg_config(0x43, 0);

	// ps/2 controller self test
	outb(PS2_CMND, 0xAA);
	do_assert(wait_read());

	if (inb(PS2_DATA) != 0x55) {
		kputs("PS/2 Controller self test failed.\n");
		return;
	}

	// individual device detection
	detect_device(0, 0xAE, 0xAB, 0x10);
	detect_device(1, 0xA8, 0xA9, 0x20);
}
예제 #6
0
파일: daemon.c 프로젝트: carriercomm/cables
int main() {
    /* using NAME_MAX prevents EINVAL on read() (twice for UTF-16 on NTFS) */
    char   buf[sizeof(struct inotify_event) + NAME_MAX*2 + 1];
    char   *crtpath, *qpath, *rqpath, *looppath, *lsthost, *lstport;
    int    sz, offset, rereg, evqok, retryid;
    struct inotify_event *iev;
    double retrytmout, lastclock;


    /* init logging */
    syslog_init();


    /* extract environment */
    crtpath  = alloc_env(CABLE_CERTS,  "/" CERTS_NAME);
    qpath    = alloc_env(CABLE_QUEUES, "/" QUEUE_NAME);
    rqpath   = alloc_env(CABLE_QUEUES, "/" RQUEUE_NAME);
    looppath = alloc_env(CABLE_HOME,   "/" LOOP_NAME);
    lsthost  = alloc_env(CABLE_HOST,   "");
    lstport  = alloc_env(CABLE_PORT,   "");


    /* initialize rng */
    if (!rand_init())
        warning("failed to initialize RNG");


    /* initialize process accounting */
    if (!init_process_acc())
        warning("failed to initialize process accounting");


    /* initialize webserver */
    if (!init_server(crtpath, qpath, rqpath, lsthost, lstport)) {
        flog(LOG_ERR, "failed to initialize webserver");
        return EXIT_FAILURE;
    }


    /* try to reregister watches as long as no signal caught */
    for (lastclock = getmontime(), retryid = 0;  !stop_requested(); ) {
        /* support empty CABLE_NOLOOP when testing, to act as pure server */
#ifdef TESTING
        if (getenv("CABLE_NOLOOP")) {
            sleepsec(RETRY_TMOUT);
            continue;
        }
#endif

        wait_reg_watches(qpath, rqpath);

        /* read events as long as no signal caught and no unmount / move_self / etc. events read */
        for (rereg = evqok = 0;  !stop_requested()  &&  !rereg; ) {
            /* wait for an event, or timeout (later blocking read() results in error) */
            retrytmout = RETRY_TMOUT + RETRY_TMOUT * (rand_shift() / 2);

            if (wait_read(inotfd, retrytmout - (getmontime() - lastclock))) {
                /* read events (non-blocking), taking care to handle interrupts due to signals */
                if ((sz = read(inotfd, buf, sizeof(buf))) == -1  &&  errno != EINTR) {
                    /* happens buffer is too small (e.g., NTFS + 255 unicode chars) */
                    warning("error while reading from inotify queue");
                    rereg = 1;
                }

                /* process all events in buffer, sz = -1 and 0 are automatically ignored */
                for (offset = 0;  offset < sz  &&  !stop_requested()  &&  !rereg;  evqok = 1) {
                    /* get handler to next event in read buffer, and update offset */
                    iev     = (struct inotify_event*) (buf + offset);
                    offset += sizeof(struct inotify_event) + iev->len;

                    /*
                      IN_IGNORED is triggered by watched directory removal / fs unmount
                      IN_MOVE_SELF is only triggered by move of actual watched directory
                      (i.e., not its parent)
                    */
                    if ((iev->mask & (IN_IGNORED | IN_UNMOUNT | IN_Q_OVERFLOW | IN_MOVE_SELF)))
                        rereg = 1;

                    /* ignore non-subdirectory events, and events with incorrect name */
                    else if (iev->len > 0  &&  (iev->mask & IN_ISDIR)  &&  is_msgdir(iev->name)) {
                        assert(iev->wd == inotqwd  ||  iev->wd == inotrqwd);
                        if (iev->wd == inotqwd  ||  iev->wd == inotrqwd) {
                            /* stop can be indicated here (while waiting for less processes) */
                            const char *qtype = (iev->wd == inotqwd) ? QUEUE_NAME : RQUEUE_NAME;
                            run_loop(qtype, iev->name, looppath);
                        }
                        else
                            flog(LOG_WARNING, "unknown watch descriptor");
                    }
                }
            }

            /*
              if sufficient time passed since last retries, retry again
            */
            if (!stop_requested()  &&  getmontime() - lastclock >= retrytmout) {
                /* alternate between queue dirs to prevent lock starvation on self-send */
                if ((retryid ^= 1))
                    retry_dir(QUEUE_NAME,  qpath,  looppath);
                else
                    retry_dir(RQUEUE_NAME, rqpath, looppath);

                lastclock = getmontime();

                /* inotify is apparently unreliable on fuse, so reregister when no events */
                if (!evqok)
                    rereg = 1;
                evqok = 0;
            }
        }
    }


    unreg_watches();

    if (!shutdown_server())
        flog(LOG_WARNING, "failed to shutdown webserver");

    dealloc_env(lstport);
    dealloc_env(lsthost);
    dealloc_env(looppath);
    dealloc_env(rqpath);
    dealloc_env(qpath);
    dealloc_env(crtpath);

    flog(LOG_INFO, "exiting");
    closelog();

    return EXIT_SUCCESS;
}
예제 #7
0
파일: ps2.c 프로젝트: sjrct/Frosk
static uchar get_config(void)
{
	outb(PS2_CMND, 0x20);
	do_assert(wait_read());
	return inb(PS2_DATA);
}