Beispiel #1
0
arg_t _ioctl(void)
{
	inoptr ino;
	uint16_t dev;

	if ((ino = getinode(fd)) == NULLINODE)
		return -1;

	if (!(isdevice(ino))) {
		udata.u_error = ENOTTY;
		return -1;
	}

	if ((request & IOCTL_SUPER) && esuper())
	        return -1;

	if (!(getperm(ino) & OTH_WR)) {
		udata.u_error = EPERM;
		return -1;
	}

	dev = ino->c_node.i_addr[0];

	/* top bit of request is reserved for kernel originated magic */
	return d_ioctl(dev, request & 0x7FFF, data);
}
Beispiel #2
0
arg_t _mknod(void)
{
	inoptr ino;
	inoptr parent;
	char fname[FILENAME_LEN + 1];

	udata.u_error = 0;

	if (!super() && ((mode & F_MASK) != F_PIPE)) {
		udata.u_error = EPERM;
		goto nogood3;
	}
	if ((ino = n_open(name, &parent)) != NULL) {
		udata.u_error = EEXIST;
		goto nogood;
	}

	if (!parent) {
		udata.u_error = ENOENT;
		return (-1);
	}

	filename(name, fname);
	ino = newfile(parent, fname);
	if(!ino)
		goto nogood3;	/* parent inode is derefed in newfile. SN */

	/* Initialize mode and dev */
	ino->c_node.i_mode = mode & ~udata.u_mask;
	ino->c_node.i_addr[0] = isdevice(ino) ? dev : 0;
	setftime(ino, A_TIME | M_TIME | C_TIME);
	wr_inode(ino);

	i_deref(ino);
	return (0);

      nogood:
	i_deref(ino);
	i_deref(parent);
      nogood3:
	return (-1);
}
Beispiel #3
0
/*
 * Copies "from" to "to".
 */
void
copy_file (const char *from, const char *to)
{
    struct stat sb;
    struct utimbuf t;
    int fdin, fdout;
    ssize_t rsize;

    TRACE (TRACE_FUNCTION, "copy(%s,%s)", from, to);

    if (noexec)
	return;

    /* If the file to be copied is a link or a device, then just create
       the new link or device appropriately. */
    if ((rsize = islink (from)) > 0)
    {
	char *source = Xreadlink (from, rsize);
	symlink (source, to);
	free (source);
	return;
    }

    if (isdevice (from))
    {
#if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
	if (stat (from, &sb) < 0)
	    error (1, errno, "cannot stat %s", from);
	mknod (to, sb.st_mode, sb.st_rdev);
#else
	error (1, 0, "cannot copy device files on this system (%s)", from);
#endif
    }
    else
    {
	/* Not a link or a device... probably a regular file. */
	if ((fdin = open (from, O_RDONLY)) < 0)
	    error (1, errno, "cannot open %s for copying", from);
	if (fstat (fdin, &sb) < 0)
	    error (1, errno, "cannot fstat %s", from);
	if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
	    error (1, errno, "cannot create %s for copying", to);
	if (sb.st_size > 0)
	{
	    char buf[BUFSIZ];
	    int n;
	    
	    for (;;) 
	    {
		n = read (fdin, buf, sizeof(buf));
		if (n == -1)
		{
#ifdef EINTR
		    if (errno == EINTR)
			continue;
#endif
		    error (1, errno, "cannot read file %s for copying", from);
		}
		else if (n == 0) 
		    break;
		
		if (write(fdout, buf, n) != n) {
		    error (1, errno, "cannot write file %s for copying", to);
		}
	    }
	}

	if (close (fdin) < 0) 
	    error (0, errno, "cannot close %s", from);
	if (close (fdout) < 0)
	    error (1, errno, "cannot close %s", to);
    }

    /* preserve last access & modification times */
    memset ((char *) &t, 0, sizeof (t));
    t.actime = sb.st_atime;
    t.modtime = sb.st_mtime;
    (void) utime (to, &t);
}
Beispiel #4
0
arg_t _open(void)
{
	int8_t uindex;
	int8_t oftindex;
	staticfast inoptr ino;
	int16_t perm;
	staticfast inoptr parent;
	char fname[FILENAME_LEN + 1];
	int trunc;
	int r;
	int w;
	int j;

	parent = NULLINODE;

	trunc = flag & O_TRUNC;
	r = (flag + 1) & 1;
	w = (flag + 1) & 2;

	if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) {
		udata.u_error = EINVAL;
		return (-1);
	}
	if ((uindex = uf_alloc()) == -1)
		return (-1);

	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	ino = n_open(name, &parent);
	if (ino) {
		i_deref(parent);
		/* O_EXCL test */
		if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
			udata.u_error = EEXIST;
			goto idrop;
		}
	} else {
		/* The n_open failed */
		if (udata.u_error == EFAULT)
			goto cantopen;
		/* New file */
		if (!(flag & O_CREAT)) {
			udata.u_error = ENOENT;
			goto cantopen;
		}
		filename(name, fname);
		/* newfile drops parent for us */
		if (parent && (ino = newfile(parent, fname))) {
			ino->c_node.i_mode =
			    (F_REG | (mode & MODE_MASK & ~udata.u_mask));
			setftime(ino, A_TIME | M_TIME | C_TIME);
			wr_inode(ino);
		} else {
			udata.u_error = ENFILE;	/* FIXME, should be set in newfile
						   not bodged to a guessed code */
			goto cantopen;
		}
	}
	/* Book our slot in case we block opening a device */
	of_tab[oftindex].o_inode = ino;

	perm = getperm(ino);
	if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) {
		udata.u_error = EACCES;
		goto cantopen;
	}
	if (w) {
		if (getmode(ino) == F_DIR ) {
			udata.u_error = EISDIR;
			goto cantopen;
		}
		if (ino->c_flags & CRDONLY) {
			udata.u_error = EROFS;
			goto cantopen;
		}
	}

	if (isdevice(ino)) {
		inoptr *iptr = &of_tab[oftindex].o_inode;
		/* d_open may block and thus ino may become invalid as may
		   parent (but we don't need it again). It may also be changed
		   by the call to dev_openi */

		if (dev_openi(iptr, flag) != 0)
			goto cantopen;

		/* May have changed */
		/* get the static pointer back in case it changed via dev 
		   usage or just because we blocked */
		ino = *iptr;
	}

	if (trunc && getmode(ino) == F_REG) {
		if (f_trunc(ino))
			goto idrop;
		for (j = 0; j < OFTSIZE; ++j)
			/* Arguably should fix at read/write */
			if (of_tab[j].o_inode == ino)
				of_tab[j].o_ptr = 0;
	}

	udata.u_files[uindex] = oftindex;

	of_tab[oftindex].o_ptr = 0;
	of_tab[oftindex].o_access = flag;	/* Save the low bits only */
	if (flag & O_CLOEXEC)
		udata.u_cloexec |= (1 << oftindex);
	/* FIXME: ATIME ? */

/*
 *         Sleep process if no writer or reader
 */
	if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1
	    && !(flag & O_NDELAY))
		psleep(ino);

        /* From the moment of the psleep ino is invalid */

	return (uindex);
      idrop:
	i_deref(ino);
      cantopen:
	oft_deref(oftindex);	/* This will call i_deref() */
      nooft:
	udata.u_files[uindex] = NO_FILE;
	return (-1);
}
Beispiel #5
0
/*
 * Copies "from" to "to".
 */
int copy_file (const char *from, const char *to, int force_overwrite, int must_exist)
{
    struct stat sb;
    struct utimbuf t;
    int fdin, fdout;
#ifdef UTIME_EXPECTS_WRITABLE
    int change_it_back = 0;
#endif

    TRACE(1,"copy(%s,%s)",PATCH_NULL(from),PATCH_NULL(to));
    if (noexec)
        return 0;

    /* If the file to be copied is a link or a device, then just create
       the new link or device appropriately. */
    if (islink (from))
    {
        char *source = xreadlink (from);
        symlink (source, to);
        xfree (source);
        return 0;
    }

    if (isdevice (from))
    {
#if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
        if (stat (from, &sb) < 0)
            error (1, errno, "cannot stat %s", fn_root(from));
        mknod (to, sb.st_mode, sb.st_rdev);
#else
        error (1, 0, "cannot copy device files on this system (%s)", fn_root(from));
#endif
    }
    else
    {
#ifdef MAC_HFS_STUFF
        /* Only use the mac specific copying routine in the client, since
           the server shouldn't have any need to handle resource forks
           (all the resource fork handling is done in the client -
            the server only handles flat files) */
        if ( !server_active ) {
            if (stat (from, &sb) < 0)
            {
                if(must_exist)
                    error (1, errno, "cannot stat %s", fn_root(from));
                else
                    return -1;
            }
            mac_copy_file(from, to, force_overwrite, must_exist);
        } else {
#endif
            /* Not a link or a device... probably a regular file. */
            if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0)
            {
                if(must_exist)
                    error (1, errno, "cannot open %s for copying", fn_root(from));
                else
                    return -1;
            }
            if (fstat (fdin, &sb) < 0)
            {
                if(must_exist)
                    error (1, errno, "cannot fstat %s", fn_root(from));
                else
                {
                    close(fdin);
                    return -1;
                }
            }
            if (force_overwrite && unlink_file (to) && !existence_error (errno))
                error (1, errno, "unable to remove %s", to);

            if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
                error (1, errno, "cannot create %s for copying", fn_root(to));
            if (sb.st_size > 0)
            {
                char buf[BUFSIZ];
                int n;

                for (;;)
                {
                    n = read (fdin, buf, sizeof(buf));
                    if (n == -1)
                    {
#ifdef EINTR
                        if (errno == EINTR)
                            continue;
#endif
                        error (1, errno, "cannot read file %s for copying", fn_root(from));
                    }
                    else if (n == 0)
                        break;

                    if (write(fdout, buf, n) != n) {
                        error (1, errno, "cannot write file %s for copying", fn_root(to));
                    }
                }

#ifdef HAVE_FSYNC
                if (fsync (fdout))
                    error (1, errno, "cannot fsync file %s after copying", fn_root(to));
#endif
            }

            if (close (fdin) < 0)
                error (0, errno, "cannot close %s", fn_root(from));
            if (close (fdout) < 0)
                error (1, errno, "cannot close %s", fn_root(to));
#ifdef MAC_HFS_STUFF
        }
#endif
    }


#ifdef UTIME_EXPECTS_WRITABLE
    if (!iswritable (to))
    {
        xchmod (to, 1);
        change_it_back = 1;
    }
#endif  /* UTIME_EXPECTS_WRITABLE  */
    /* now, set the times for the copied file to match those of the original */
    memset ((char *) &t, 0, sizeof (t));
    t.actime = sb.st_atime;
    t.modtime = sb.st_mtime;
    (void) utime (to, &t);
#ifdef UTIME_EXPECTS_WRITABLE
    if (change_it_back)
        xchmod (to, 0);
#endif  /*  UTIME_EXPECTS_WRITABLE  */
    return 0;
}
Beispiel #6
0
/*
 * Copies "from" to "to", decompressing "from" on the fly
 */
int copy_and_unzip_file (const char *from, const char *to, int force_overwrite, int must_exist)
{
    struct stat sb;
    struct utimbuf t;
    int fdin, fdout;
    z_stream zstr = {0};
    int zstatus;
    char buf[BUFSIZ*10];
    char zbuf[BUFSIZ*20];
    int n;
#ifdef UTIME_EXPECTS_WRITABLE
    int change_it_back = 0;
#endif

    TRACE(1,"copy_and_unzip(%s,%s)",PATCH_NULL(from),PATCH_NULL(to));
    if (noexec)
        return 0;

    /* If the file to be copied is a link or a device, then just create
       the new link or device appropriately. */
    if (islink (from))
    {
        char *source = xreadlink (from);
        symlink (source, to);
        xfree (source);
        return 0;
    }

    if (isdevice (from))
    {
#if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_ST_RDEV)
        if (stat (from, &sb) < 0)
            error (1, errno, "cannot stat %s", fn_root(from));
        mknod (to, sb.st_mode, sb.st_rdev);
#else
        error (1, 0, "cannot copy device files on this system (%s)", fn_root(from));
#endif
    }
    else
    {
        /* Not a link or a device... probably a regular file. */
        if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0)
        {
            if(must_exist)
                error (1, errno, "cannot open %s for copying", fn_root(from));
            else
                return -1;
        }
        if (fstat (fdin, &sb) < 0)
        {
            if(must_exist)
                error (1, errno, "cannot fstat %s", fn_root(from));
            else
            {
                close(fdin);
                return -1;
            }
        }
        if (force_overwrite && unlink_file (to) && !existence_error (errno))
            error (1, errno, "unable to remove %s", to);

        if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
            error (1, errno, "cannot create %s for copying", to);

        zstatus = inflateInit2 (&zstr, 47);
        if(zstatus != Z_OK)
            error(1, 0, "expansion error (INIT): (%d)%s", zstatus,zstr.msg);

        if (sb.st_size > 0)
        {
            for (;;)
            {
                n = read (fdin, buf, sizeof(buf));
                if (n == -1)
                {
#ifdef EINTR
                    if (errno == EINTR)
                        continue;
#endif
                    error (1, errno, "cannot read file %s for copying", fn_root(from));
                }
                else if (n == 0)
                    break;

                zstr.next_in = (Bytef*)buf;
                zstr.avail_in = n;
                while(zstr.avail_in)
                {
                    zstr.next_out = (Bytef*)zbuf;
                    zstr.avail_out = sizeof(zbuf);
                    zstatus = inflate (&zstr, 0);
                    if(zstatus != Z_OK && zstatus != Z_STREAM_END)
                        error(1,0, "expansion error (inflate): (%d)%s", zstatus,zstr.msg);

                    n = sizeof(zbuf)-zstr.avail_out;
                    if (n && write(fdout, zbuf, n) != n) {
                        error (1, errno, "cannot write file %s for copying", to);
                    }
                }
                if(zstatus == Z_STREAM_END)
                    break;
            }

#ifdef HAVE_FSYNC
            if (fsync (fdout))
                error (1, errno, "cannot fsync file %s after copying", fn_root(to));
#endif

        }

        zstr.next_out = (Bytef*)zbuf;
        zstr.avail_out = sizeof(zbuf);
        zstatus = inflate (&zstr, Z_FINISH);
        if(zstatus != Z_OK && zstatus != Z_STREAM_END)
            error(1,0, "expansion error (Z_FINISH): (%d)%s", zstatus,zstr.msg);
        n = sizeof(zbuf)-zstr.avail_out;
        if (n && write(fdout, zbuf, n) != n) {
            error (1, errno, "cannot write file %s for copying", fn_root(to));
        }

        zstr.next_in = (Bytef*)buf;
        zstr.avail_in = 0;
        zstr.next_out = (Bytef*)zbuf;
        zstr.avail_out = sizeof(zbuf);
        zstatus = inflateEnd(&zstr);
        if(zstatus != Z_OK)
            error(1,0, "expansion error: %s", zstr.msg);

        if (close (fdin) < 0)
            error (0, errno, "cannot close %s", fn_root(from));
        if (close (fdout) < 0)
            error (1, errno, "cannot close %s", fn_root(to));
    }

#ifdef UTIME_EXPECTS_WRITABLE
    if (!iswritable (to))
    {
        xchmod (to, 1);
        change_it_back = 1;
    }
#endif  /* UTIME_EXPECTS_WRITABLE  */
    /* now, set the times for the copied file to match those of the original */
    memset ((char *) &t, 0, sizeof (t));
    t.actime = sb.st_atime;
    t.modtime = sb.st_mtime;
    (void) utime (to, &t);
#ifdef UTIME_EXPECTS_WRITABLE
    if (change_it_back)
        xchmod (to, 0);
#endif  /*  UTIME_EXPECTS_WRITABLE  */
    return 0;
}