예제 #1
0
파일: sysfile.c 프로젝트: 7perl/akaros
static int growfd(struct fgrp *f, int fd)
{
	int n;
	struct chan **nfd, **ofd;

	if (fd < f->nfd) {
		return 0;
	}
	/* want to grow by a reasonable amount (delta), but also make sure we can
	 * handle the fd we're asked for */
	n = MAX(f->nfd, fd + 1) + DELTAFD;
	if (n > MAXNFD)
		n = MAXNFD;
	if (fd >= n) {
		set_errno(EMFILE);
		set_errstr("Asked for FD %d, more than %d\n", fd, MAXNFD);
		return -1;
	}
	nfd = kzmalloc(n * sizeof(struct chan *), 0);
	if (nfd == NULL) {
		set_errno(ENOMEM);
		set_errstr("Failed to growfd for FD %d, OOM\n", fd);
		return -1;
	}
	ofd = f->fd;
	memmove(nfd, ofd, f->nfd * sizeof(struct chan *));
	f->fd = nfd;
	f->nfd = n;
	kfree(ofd);
	return 0;
}
예제 #2
0
static vbi_bool
valid_ttx_subpage_range		(vbi_sliced_filter *	sf,
				 vbi_pgno		pgno,
				 vbi_subno		first_subno,
				 vbi_subno		last_subno)
{
	if (unlikely (!valid_ttx_page (pgno))) {
		set_errstr (sf, _("Invalid Teletext page number %x."),
			    pgno);
		errno = VBI_ERR_INVALID_PGNO;
		return FALSE;
	}

	if (likely ((unsigned int) first_subno <= MAX_SUBNO
		    && (unsigned int) last_subno <= MAX_SUBNO))
		return TRUE;

	if (first_subno == last_subno) {
		set_errstr (sf, _("Invalid Teletext subpage number %x."),
			    first_subno);
	} else {
		set_errstr (sf, _("Invalid Teletext subpage range %x-%x."),
			    first_subno, last_subno);
	}

	errno = VBI_ERR_INVALID_SUBNO;

	return FALSE;
}
예제 #3
0
파일: dial.c 프로젝트: dhootha/akaros
/*
 *  call up the connection server and get a translation
 */
static int nettrans(char *addr, char *naddr, int na, char *file, int nf)
{
	int i, fd;
	char buf[Maxpath];
	char netdir[NETPATHLEN];
	char *p, *p2;
	long n;

	/*
	 *  parse, get network directory
	 */
	p = strchr(addr, '!');
	if (p == 0) {
		set_errstr("bad dial string: %s", addr);
		return -1;
	}
	if (*addr != '/') {
		strlcpy(netdir, "/net", sizeof(netdir));
	} else {
		for (p2 = p; *p2 != '/'; p2--) ;
		i = p2 - addr;
		if (i == 0 || i >= sizeof(netdir)) {
			set_errstr("bad dial string: %s", addr);
			return -1;
		}
		strlcpy(netdir, addr, i + 1);
		addr = p2 + 1;
	}

	/*
	 *  ask the connection server
	 */
	snprintf(buf, sizeof(buf), "%s/cs", netdir);
	fd = sysopen(buf, O_RDWR);
	if (fd < 0)
		return identtrans(netdir, addr, naddr, na, file, nf);
	if (syswrite(fd, addr, strlen(addr)) < 0) {
		sysclose(fd);
		return -1;
	}
	sysseek(fd, 0, 0);
	n = sysread(fd, buf, sizeof(buf) - 1);
	sysclose(fd);
	if (n <= 0)
		return -1;
	buf[n] = 0;

	/*
	 *  parse the reply
	 */
	p = strchr(buf, ' ');
	if (p == 0)
		return -1;
	*p++ = 0;
	strlcpy(naddr, p, na);
	strlcpy(file, buf, nf);
	return 0;
}
예제 #4
0
파일: pipe.c 프로젝트: GanShun/akaros
static int pipetapfd(struct chan *chan, struct fd_tap *tap, int cmd)
{
	int ret;
	Pipe *p;
	int which = 1;
	uint64_t kludge;

	p = chan->aux;
	kludge = (uint64_t)p;
#define DEVPIPE_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
                                 FDTAP_FILT_HANGUP | FDTAP_FILT_ERROR)

	switch (NETTYPE(chan->qid.path)) {
	case Qdata0:
		which = 0;
		/* fall through */
	case Qdata1:
		kludge |= which;

		if (tap->filter & ~DEVPIPE_LEGAL_DATA_TAPS) {
			set_errno(ENOSYS);
			set_errstr("Unsupported #%s data tap %p, must be %p", devname(),
			           tap->filter, DEVPIPE_LEGAL_DATA_TAPS);
			return -1;
		}
		spin_lock(&p->tap_lock);
		switch (cmd) {
		case (FDTAP_CMD_ADD):
			if (SLIST_EMPTY(&p->data_taps[which]))
				qio_set_wake_cb(p->q[which], pipe_wake_cb, (void *)kludge);
			SLIST_INSERT_HEAD(&p->data_taps[which], tap, link);
			ret = 0;
			break;
		case (FDTAP_CMD_REM):
			SLIST_REMOVE(&p->data_taps[which], tap, fd_tap, link);
			if (SLIST_EMPTY(&p->data_taps[which]))
				qio_set_wake_cb(p->q[which], 0, (void *)kludge);
			ret = 0;
			break;
		default:
			set_errno(ENOSYS);
			set_errstr("Unsupported #%s data tap command %p", devname(), cmd);
			ret = -1;
		}
		spin_unlock(&p->tap_lock);
		return ret;
	default:
		set_errno(ENOSYS);
		set_errstr("Can't tap #%s file type %d", devname(),
		           NETTYPE(chan->qid.path));
		return -1;
	}
}
예제 #5
0
파일: login.c 프로젝트: vanzhiganov/jftpgw
static
int login_readwelcome(struct clientinfo *clntinfo) {
	/* Read the welcome line */
	clntinfo->login.welcomemsg = readall(clntinfo->serversocket);
	if (!clntinfo->login.welcomemsg.fullmsg) {
		/* an error occurred */
		if (timeout) {
			jlog(2, "Timeout in %s line %d\n", __FILE__ ,__LINE__);
			err_time_readline(clntinfo->clientsocket);
		} else {
			set_errstr("Server closed the connection");
			err_readline(clntinfo->clientsocket);
		}
		return CMD_ABORT;
	}

	jlog(9, "Connected to %s, got \"%s\" as welcome message",
		clntinfo->destination, clntinfo->login.welcomemsg.fullmsg);

	if (!checkbegin(clntinfo->login.welcomemsg.lastmsg, "220 ")) {
		jlog(2, "Not a valid FTP server response (%s)",
				clntinfo->login.welcomemsg.fullmsg);
		say(clntinfo->clientsocket,clntinfo->login.welcomemsg.fullmsg);

		free(clntinfo->login.welcomemsg.fullmsg);
		clntinfo->login.welcomemsg.fullmsg = (char*) 0;
		clntinfo->login.welcomemsg.lastmsg = (char*) 0;
		return CMD_ERROR;
	}
	return CMD_HANDLED;
}
예제 #6
0
static vbi_bool
decode_teletext			(vbi_sliced_filter *	sf,
				 vbi_bool *		keep,
				 const uint8_t		buffer[42],
				 unsigned int		line)
{
	int pmag;
	unsigned int magazine;
	unsigned int packet;
	unsigned int keep_mag_set;

	line = line;

	keep_mag_set = sf->keep_mag_set_next;

	pmag = vbi_unham16p (buffer);
	if (unlikely (pmag < 0)) {
		set_errstr (sf, _("Hamming error in Teletext "
				  "packet/magazine number."));
		errno = VBI_ERR_PARITY;
		return FALSE;
	}

	magazine = pmag & 7;
	if (0 == magazine)
		magazine = 8;

	packet = pmag >> 3;

	switch (packet) {
	case 0: /* page header */
		if (!decode_teletext_packet_0 (sf, &keep_mag_set,
					       buffer, magazine))
			return FALSE;
		break;

	case 1 ... 25: /* page body */
		break;

	case 26: /* page enhancement packet */
	case 27: /* page linking */
	case 28:
	case 29: /* level 2.5/3.5 enhancement */
		break;

	case 30:
	case 31: /* IDL packet (ETS 300 708). */
		*keep = FALSE;
		return TRUE;

	default:
		assert (0);
	}

	*keep = !!(keep_mag_set & (1 << magazine));

	return TRUE;
}
예제 #7
0
static vbi_bool
valid_ttx_page_range		(vbi_sliced_filter *	sf,
				 vbi_pgno		first_pgno,
				 vbi_pgno		last_pgno)
{
	if (likely (valid_ttx_page (first_pgno)
		    && valid_ttx_page (last_pgno)))
		return TRUE;

	if (first_pgno == last_pgno) {
		set_errstr (sf, _("Invalid Teletext page number %x."),
			    first_pgno);
	} else {
		set_errstr (sf, _("Invalid Teletext page range %x-%x."),
			    first_pgno, last_pgno);
	}

	errno = VBI_ERR_INVALID_PGNO;

	return FALSE;
}
예제 #8
0
파일: vmm.c 프로젝트: anandab/akaros
/* Initializes a process to run virtual machine contexts, returning the number
 * initialized, optionally setting errno */
int vmm_struct_init(struct proc *p, unsigned int nr_guest_pcores,
                    struct vmm_gpcore_init *u_gpcis, int flags)
{
	struct vmm *vmm = &p->vmm;
	unsigned int i;
	struct vmm_gpcore_init gpci;

	if (flags & ~VMM_ALL_FLAGS) {
		set_errstr("%s: flags is 0x%lx, VMM_ALL_FLAGS is 0x%lx\n", __func__,
		           flags, VMM_ALL_FLAGS);
		set_errno(EINVAL);
		return 0;
	}
	vmm->flags = flags;
	if (!x86_supports_vmx) {
		set_errno(ENODEV);
		return 0;
	}
	qlock(&vmm->qlock);
	if (vmm->vmmcp) {
		set_errno(EINVAL);
		qunlock(&vmm->qlock);
		return 0;
	}
	/* Set this early, so cleanup checks the gpc array */
	vmm->vmmcp = TRUE;
	nr_guest_pcores = MIN(nr_guest_pcores, num_cores);
	vmm->amd = 0;
	vmm->guest_pcores = kzmalloc(sizeof(void*) * nr_guest_pcores, KMALLOC_WAIT);
	for (i = 0; i < nr_guest_pcores; i++) {
		if (copy_from_user(&gpci, &u_gpcis[i],
		                   sizeof(struct vmm_gpcore_init))) {
			set_error(EINVAL, "Bad pointer %p for gps", u_gpcis);
			break;
		}
		vmm->guest_pcores[i] = create_guest_pcore(p, &gpci);
		/* If we failed, we'll clean it up when the process dies */
		if (!vmm->guest_pcores[i]) {
			set_errno(ENOMEM);
			break;
		}
	}
	vmm->nr_guest_pcores = i;
	for (int i = 0; i < VMM_VMEXIT_NR_TYPES; i++)
		vmm->vmexits[i] = 0;
	qunlock(&vmm->qlock);
	return i;
}
예제 #9
0
/**
 * @brief Sliced VBI filter coroutine.
 * @param sf Sliced VBI filter context allocated with
 *   vbi_sliced_filter_new().
 * @param sliced_out Filtered sliced data will be stored here.
 *   @a sliced_out and @a sliced_in can be the same.
 * @param n_lines_out The number of sliced lines in the
 *   @a sliced_out buffer will be stored here.
 * @param max_lines_out The maximum number of sliced lines this
 *   function may store in the @a sliced_out buffer.
 * @param sliced_in The sliced data to be filtered.
 * @param n_lines_in Pointer to a variable which contains the
 *   number of sliced lines to be read from the @a sliced_in buffer.
 *   When the function fails, it stores here the number of sliced
 *   lines successfully read so far.
 *
 * This function takes one video frame worth of sliced VBI data and
 * filters out the lines which match the selected criteria.
 *
 * @returns
 * @c TRUE on success. @c FALSE if there is not enough room in the
 * output buffer to store the filtered data, or when the function
 * detects an error in the sliced input data. On failure the
 * @a sliced_out buffer will contain the data successfully filtered
 * so far, @a *n_lines_out will be valid, and @a *n_lines_in will
 * contain the number of lines read so far.
 *
 * @since 99.99.99
 */
vbi_bool
vbi_sliced_filter_cor		(vbi_sliced_filter *	sf,
				 vbi_sliced *		sliced_out,
				 unsigned int *		n_lines_out,
				 unsigned int		max_lines_out,
				 const vbi_sliced *	sliced_in,
				 unsigned int *		n_lines_in)
{
	unsigned int in;
	unsigned int out;

	assert (NULL != sf);
	assert (NULL != sliced_out);
	assert (NULL != n_lines_out);
	assert (NULL != sliced_in);

	errno = 0;

	out = 0;

	for (in = 0; in < *n_lines_in; ++in) {
		vbi_bool pass_through;

		pass_through = FALSE;

		if (sliced_in[in].id & sf->keep_services) {
			pass_through = TRUE;
		} else {
			switch (sliced_in[in].id) {
			case VBI_SLICED_TELETEXT_B_L10_625:
			case VBI_SLICED_TELETEXT_B_L25_625:
			case VBI_SLICED_TELETEXT_B_625:
				if (!decode_teletext (sf,
						      &pass_through,
						      sliced_in[in].data,
						      sliced_in[in].line))
					goto failed;
				break;

			default:
				break;
			}
		}

		if (pass_through) {
			if (out >= max_lines_out) {
				set_errstr (sf, _("Output buffer overflow."));
				errno = VBI_ERR_BUFFER_OVERFLOW;
				goto failed;
			}

			memcpy (&sliced_out[out],
				&sliced_in[in],
				sizeof (*sliced_out));
			++out;
		}
	}

	*n_lines_out = out;

	return TRUE;

 failed:
	*n_lines_in = in;
	*n_lines_out = out;

	return FALSE;
}
예제 #10
0
static vbi_bool
decode_teletext_packet_0	(vbi_sliced_filter *	sf,
				 unsigned int *		keep_mag_set,
				 const uint8_t		buffer[42],
				 unsigned int		magazine)
{
	int page;
	int flags;
	vbi_pgno pgno;
	unsigned int mag_set;

	page = vbi_unham16p (buffer + 2);
	if (unlikely (page < 0)) {
		set_errstr (sf, _("Hamming error in Teletext "
				  "page number."));
		errno = VBI_ERR_PARITY;
		return FALSE;
	}

	if (0xFF == page) {
		/* Filler, discard. */
		*keep_mag_set = 0;
		return TRUE;
	}

	pgno = magazine * 0x100 + page;

	flags = vbi_unham16p (buffer + 4)
		| (vbi_unham16p (buffer + 6) << 8)
		| (vbi_unham16p (buffer + 8) << 16);
	if (unlikely (flags < 0)) {
		set_errstr (sf, _("Hamming error in Teletext "
				  "packet flags."));
		errno = VBI_ERR_PARITY;
		return FALSE;
	}

	/* Blank lines are not transmitted and there's no page end mark,
	   so Teletext decoders wait for another page before displaying
	   the previous one. In serial transmission mode that is any
	   page, in parallel mode a page of the same magazine. */
	if (flags & VBI_SERIAL) {
		mag_set = -1;
	} else {
		mag_set = 1 << magazine;
	}

	if (!vbi_is_bcd (pgno)) {
		/* Page inventories and TOP pages (e.g. to
		   find subtitles), DRCS and object pages, etc. */
		if (sf->keep_ttx_system_pages)
			goto match;
	} else {
		vbi_subno subno;

		subno = flags & 0x3F7F;

		if (vbi_page_table_contains_subpage (sf->keep_ttx_pages,
						      pgno, subno))
			goto match;
	}

	if (*keep_mag_set & mag_set) {
		/* To terminate the previous page we keep the header
		   packet of this page (keep_mag_set) but discard all
		   following packets (keep_mag_set_next). */
		sf->keep_mag_set_next = *keep_mag_set & ~mag_set;
	} else if (sf->start) {
		/* Keep the very first page header and its timestamp,
		   which is important for subtitle timing. */
		*keep_mag_set = mag_set;
		sf->keep_mag_set_next = 0;
	} else {
		/* Discard this and following packets until we
		   find another header packet. */
		*keep_mag_set &= ~mag_set;
		sf->keep_mag_set_next = *keep_mag_set;
	}

	sf->start = FALSE;

	return TRUE;

 match:
	/* Keep this and following packets. */
	*keep_mag_set |= mag_set;
	sf->keep_mag_set_next = *keep_mag_set;

	sf->start = FALSE;

	return TRUE;
}
예제 #11
0
파일: dev.c 프로젝트: rajuvindane/akaros
struct walkqid *devwalk(struct chan *c,
                        struct chan *nc, char **name, int nname,
                        struct dirtab *tab, int ntab, Devgen * gen)
{
    ERRSTACK(1);
    int i, j;
    volatile int alloc;			/* to keep waserror from optimizing this out */
    struct walkqid *wq;
    char *n;
    struct dir dir;

    if (nname > 0)
        isdir(c);

    alloc = 0;
    wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
                  KMALLOC_WAIT);
    if (waserror()) {
        if (alloc && wq->clone != NULL)
            cclose(wq->clone);
        kfree(wq);
        poperror();
        return NULL;
    }
    if (nc == NULL) {
        nc = devclone(c);
        /* inferno was setting this to 0, assuming it was devroot.  lining up
         * with chanrelease and newchan */
        nc->type = -1;	/* device doesn't know about this channel yet */
        alloc = 1;
    }
    wq->clone = nc;

    dir.qid.path = 0;
    for (j = 0; j < nname; j++) {
        if (!(nc->qid.type & QTDIR)) {
            if (j == 0)
                error(Enotdir);
            goto Done;
        }
        n = name[j];
        if (strcmp(n, ".") == 0) {
Accept:
            wq->qid[wq->nqid++] = nc->qid;
            continue;
        }
        if (strcmp(n, "..") == 0) {
            (*gen) (nc, NULL, tab, ntab, DEVDOTDOT, &dir);
            nc->qid = dir.qid;
            goto Accept;
        }
        /*
         * Ugly problem: If we're using devgen, make sure we're
         * walking the directory itself, represented by the first
         * entry in the table, and not trying to step into a sub-
         * directory of the table, e.g. /net/net. Devgen itself
         * should take care of the problem, but it doesn't have
         * the necessary information (that we're doing a walk).
         */
        if (gen == devgen && nc->qid.path != tab[0].qid.path)
            goto Notfound;
        dir.qid.path = 0;
        for (i = 0;; i++) {
            switch ((*gen) (nc, n, tab, ntab, i, &dir)) {
            case -1:
                printd("DEVWALK -1, i was %d, want path %p\n", i,
                       c->qid.path);
Notfound:
                set_errno(ENOENT);
                if (j == 0)
                    error(Enonexist);
                set_errstr(Enonexist);
                goto Done;
            case 0:
                printd("DEVWALK continue, i was %d\n", i);
                continue;
            case 1:
                printd
                ("DEVWALK gen returns path %p name %s, want path %p\n",
                 dir.qid.path, dir.name, c->qid.path);
                if (strcmp(n, dir.name) == 0) {
                    nc->qid = dir.qid;
                    goto Accept;
                }
                continue;
            }
        }
    }
    /*
     * We processed at least one name, so will return some data.
     * If we didn't process all nname entries succesfully, we drop
     * the cloned channel and return just the Qids of the walks.
     */
Done:
    poperror();
    if (wq->nqid < nname) {
        if (alloc)
            cclose(wq->clone);
        wq->clone = NULL;
    } else if (wq->clone) {
        /* attach cloned channel to same device */
        wq->clone->type = c->type;
    }
    return wq;
}
예제 #12
0
파일: dial.c 프로젝트: dhootha/akaros
static int call(char *clone, char *dest, DS * ds)
{
	int fd, cfd, n, retval;
	char *name, *data, *err, *p;

	name = kmalloc(Maxpath, KMALLOC_WAIT);
	data = kmalloc(Maxpath, KMALLOC_WAIT);
	err = kmalloc(ERRMAX, KMALLOC_WAIT);

	cfd = sysopen(clone, O_RDWR);
	if (cfd < 0) {
		kerrstr(err, ERRMAX);
		set_errstr("%s (%s)", err, clone);
		retval = -1;
		goto out;
	}

	/* get directory name */
	n = sysread(cfd, name, Maxpath - 1);
	if (n < 0) {
		kerrstr(err, ERRMAX);
		sysclose(cfd);
		set_errstr("read %s: %s", clone, err);
		retval = -1;
		goto out;
	}
	name[n] = 0;
	for (p = name; *p == ' '; p++) ;
	snprintf(name, Maxpath, "%ld", strtoul(p, 0, 0));
	p = strrchr(clone, '/');
	*p = 0;
	if (ds->dir)
		snprintf(ds->dir, NETPATHLEN, "%s/%s", clone, name);
	snprintf(data, Maxpath, "%s/%s/data", clone, name);

	/* connect */
	if (ds->local)
		snprintf(name, Maxpath, "connect %s %s", dest, ds->local);
	else
		snprintf(name, Maxpath, "connect %s", dest);
	if (syswrite(cfd, name, strlen(name)) < 0) {
		err[0] = 0;
		kerrstr(err, ERRMAX);
		sysclose(cfd);
		set_errstr("%s (%s)", err, name);
		retval = -1;
		goto out;
	}

	/* open data connection */
	fd = sysopen(data, O_RDWR);
	if (fd < 0) {
		err[0] = 0;
		kerrstr(err, ERRMAX);
		set_errstr("%s (%s)", err, data);
		sysclose(cfd);
		retval = -1;
		goto out;
	}
	if (ds->cfdp)
		*ds->cfdp = cfd;
	else
		sysclose(cfd);
	retval = fd;
out:
	kfree(name);
	kfree(data);
	kfree(err);

	return retval;
}
예제 #13
0
파일: dial.c 프로젝트: dhootha/akaros
static int csdial(DS * ds)
{
	int n, fd, rv = -1;
	char *p, *buf, *clone, *err, *besterr;

	buf = kmalloc(Maxstring, KMALLOC_WAIT);
	clone = kmalloc(Maxpath, KMALLOC_WAIT);
	err = kmalloc(ERRMAX, KMALLOC_WAIT);
	besterr = kmalloc(ERRMAX, KMALLOC_WAIT);
	/*
	 *  open connection server
	 */
	snprintf(buf, Maxstring, "%s/cs", ds->netdir);
	fd = sysopen(buf, O_RDWR);
	if (fd < 0) {
		/* no connection server, don't translate */
		snprintf(clone, Maxpath, "%s/%s/clone", ds->netdir, ds->proto);
		rv = call(clone, ds->rem, ds);
		goto out;
	}

	/*
	 *  ask connection server to translate
	 */
	snprintf(buf, Maxstring, "%s!%s", ds->proto, ds->rem);
	if (syswrite(fd, buf, strlen(buf)) < 0) {
		kerrstr(err, ERRMAX);
		sysclose(fd);
		set_errstr("%s (%s)", err, buf);
		goto out;
	}

	/*
	 *  loop through each address from the connection server till
	 *  we get one that works.
	 */
	*besterr = 0;
	strlcpy(err, errno_to_string(ECONNRESET), ERRMAX);
	sysseek(fd, 0, 0);
	while ((n = sysread(fd, buf, Maxstring - 1)) > 0) {
		buf[n] = 0;
		p = strchr(buf, ' ');
		if (p == 0)
			continue;
		*p++ = 0;
		rv = call(buf, p, ds);
		if (rv >= 0)
			break;
		err[0] = 0;
		kerrstr(err, ERRMAX);
		if (strstr(err, "does not exist") == 0)
			memmove(besterr, err, ERRMAX);
	}
	sysclose(fd);

	if (rv < 0 && *besterr)
		kerrstr(besterr, ERRMAX);
	else
		kerrstr(err, ERRMAX);
out:
	kfree(buf);
	kfree(clone);
	kfree(err);
	kfree(besterr);
	return rv;
}