Example #1
0
// private members, they are called in background thread
void CShareManager::mount(const QSharedPointer<SShare> &p)
{
	CShareSet::iterator it = mounted_.find(p);
	if(it != mounted_.end())	{
		errors_.push_back( qMakePair(p, qMakePair(0, QString("Share already exists") ) ) );
		emit hasErrors();
		return;
	}
	bool needToRemoveDir = false;
	try	{
		mounter_->mkdir(*p);
		needToRemoveDir = true;
	}
	catch(CShareMounterInterface::CMountError &e)	{
		if(e.err() != EEXIST)	{
			errors_.push_back( qMakePair(p, qMakePair(e.err(), QString(e.what()) ) ) );
			emit hasErrors();
		}
	}
	try	{
		mounter_->mount(*p);
		emit mounted(mounter_->mountPoint() + p->name);
		mounted_.insert(p);
	}
	catch(CShareMounterInterface::CMountError &e)	{
		errors_.push_back( qMakePair(p, qMakePair(e.err(), QString(e.what()) ) ) );
		emit hasErrors();
	}
	if(needToRemoveDir)	{
		try	{	mounter_->rmdir(*p);		}
		catch(CShareMounterInterface::CMountError &e)	{}
	}
}
Example #2
0
void RootMount::finish( int exitCode , QProcess::ExitStatus exitStatus )
{
    p->error_str = p->process->readAllStandardError();
    if( exitStatus == QProcess::CrashExit )
        p->error_str.append( "\nrootmount crashed" );

    QTest::qWait( 137 );
    read_mtab();

    while( !p->mounted.isEmpty() )
    {
        const QString & file = p->mounted.dequeue();

        if( isMount( file ) )
        {
            emit mounted( true );
        }
        else
        {
            emit mounted( false );
            p->error_str.append( "\n" + tr("Can't mount %1").arg(file) );
        }
    }

    while( !p->unmounted.isEmpty() )
    {
        const QString & file = p->unmounted.dequeue();

        if( !isMount( file ) )
        {
            emit unmounted( true );
        }
        else
        {
            emit unmounted( false );
            p->error_str.append( "\n" + tr("Can't unmount %1").arg(file) );
        }
    }

    emit finished( exitCode );

    if( !p->error_str.isEmpty() )
        emit error( p->error_str );

    if( p->queue.isEmpty() )
        dropProcess();
}
Example #3
0
void Hdd::configChanged()
{
    KConfigGroup cg = config();
    QStringList sources = cg.readEntry("uuids", mounted());
    setSources(sources);
    setInterval(cg.readEntry("interval", 2) * 60 * 1000);
    connectToEngine();
}
Example #4
0
void MenuDiskItem::diskButtonClicked()
{
    if (!mDevice->isMounted())
        mDevice->mount();
    else
        mounted();

    qobject_cast<QWidget*>(parent())->hide();
}
Example #5
0
void MenuDiskItem::diskButtonClicked()
{
    mDiskButtonClicked = true;
    Solid::StorageAccess* di = mDevice.as<Solid::StorageAccess>();
    if (!di->isAccessible())
        di->setup();
    else
        mounted(Solid::NoError, QString(), mDevice.udi());

    qobject_cast<QWidget*>(parent())->hide();
}
Example #6
0
MenuDiskItem::MenuDiskItem(RazorMountDevice *device, QWidget *parent)
    : QWidget(parent),
      mDevice(device)
{
    setupUi(this);
    eject->setIcon(XdgIcon::fromTheme("media-eject"));

    connect(device, SIGNAL(destroyed()),
              this, SLOT(free()));

    connect(device, SIGNAL(changed()),
              this, SLOT(update()));

    connect(device, SIGNAL(mounted()),
              this, SLOT(mounted()));

    connect(device, SIGNAL(unmounted()),
              this, SLOT(unmounted()));

    update();
}
Example #7
0
/*
 * - set mount_point to NULL
 * - if name is mounted (search mnttab)
 *   - if it is a device, clear rflag
 *   - if mounted on /, /usr, or /var, set corefs
 *   - if corefs and read-only, set hotroot and continue
 *   - if errorlocked, continue
 *   - if preening, bail
 *   - ask user whether to continue, bail if not
 * - if it is a device and not mounted and rflag, convert
 *   name to raw version
 */
static int
check_mount_state(caddr_t devstr, size_t str_size)
{
	int corefs = 0;
	int is_dev = 0;
	struct stat statb;

	if (stat(devstr, &statb) < 0) {
		exitstat = EXNOSTAT;
		errexit("fsck: could not stat %s: %s", devstr, strerror(errno));
	}
	if (S_ISCHR(statb.st_mode) || S_ISBLK(statb.st_mode))
		is_dev = 1;

	/*
	 * mounted() will update mount_point when returning true.
	 */
	mount_point = NULL;
	if ((mountedfs = mounted(devstr, devstr, str_size)) != M_NOMNT) {
		if (is_dev)
			rflag = 0;
		corefs = which_corefs(mount_point);
		if (corefs && (mountedfs == M_RO)) {
			hotroot++;
		} else if (errorlocked) {
			goto carry_on;
		} else if (preen) {
			exitstat = EXMOUNTED;
			pfatal("%s IS CURRENTLY MOUNTED%s.",
			    devstr, mountedfs == M_RW ? " READ/WRITE" : "");
		} else {
			if (!nflag) {
				pwarn("%s IS CURRENTLY MOUNTED READ/%s.",
				    devstr, mountedfs == M_RW ? "WRITE" :
				    "ONLY");
				if (reply("CONTINUE") == 0) {
					exitstat = EXMOUNTED;
					errexit("Program terminated");
				}
			} else {
				pwarn("%s IS CURRENTLY MOUNTED READ/%s.\n",
				    devstr, mountedfs == M_RW ? "WRITE" :
				    "ONLY");
			}
		}
	} else if (is_dev && rflag) {
		(void) strlcpy(devstr, rawname(devstr), str_size);
	}

carry_on:
	return (corefs);
}
Example #8
0
void Mounter::onStarted()
{
    qCDebug(KDECONNECT_PLUGIN_SFTP) << "Process started";
    m_started = true;
    Q_EMIT mounted();
    
    connect(m_proc.data(), &KProcess::readyReadStandardError, [this]() {
        qCDebug(KDECONNECT_PLUGIN_SFTP) << "stderr: " << m_proc->readAll();
    });
    connect(m_proc.data(), &KProcess::readyReadStandardOutput, [this]() {
        qCDebug(KDECONNECT_PLUGIN_SFTP) << "stdout:" << m_proc->readAll();
    });
}
Example #9
0
bool Tire::mountable() const
{
    if(_trashdate != _buydate)
        return false;

    if(_car->tireMounted() + _quantity > _car->nbtire())
        return false;

    if(mounted())
        return false;

    return true;
}
Example #10
0
MenuDiskItem::MenuDiskItem(LxQt::MountDevice *device, QWidget *parent):
    QFrame(parent),
    mDevice(device)
{
    mDiskButton = new QToolButton(this);
    mDiskButton->setObjectName("DiskButton");
    mDiskButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    mDiskButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    connect(mDiskButton, SIGNAL(clicked()), this, SLOT(diskButtonClicked()));

    mEjectButton =  new QToolButton(this);
    mEjectButton->setObjectName("EjectButton");
    connect(mEjectButton, SIGNAL(clicked()), this, SLOT(ejectButtonClicked()));

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(mDiskButton);
    layout->addWidget(mEjectButton);
    this->setLayout(layout);

    layout->setMargin(0);
    layout->setSpacing(0);

    mEjectButton->setIcon(XdgIcon::fromTheme("media-eject"));

    connect(device, SIGNAL(destroyed()),
              this, SLOT(free()));

    connect(device, SIGNAL(changed()),
              this, SLOT(update()));

    connect(device, SIGNAL(mounted()),
              this, SLOT(mounted()));

    connect(device, SIGNAL(unmounted()),
              this, SLOT(unmounted()));

    update();
}
Example #11
0
bool Mounter::wait()
{
    if (m_started)
    {
        return true;
    }
    
    qCDebug(KDECONNECT_PLUGIN_SFTP) << "Starting loop to wait for mount";
    
    MountLoop loop;
    connect(this, SIGNAL(mounted()), &loop, SLOT(successed()));
    connect(this, SIGNAL(failed(QString)), &loop, SLOT(failed()));
    return loop.exec();
}
Example #12
0
void Mounter::onStarted()
{
    qCDebug(KDECONNECT_PLUGIN_SFTP) << "Process started";
    m_started = true;
    Q_EMIT mounted();

    //m_proc->setStandardOutputFile("/tmp/kdeconnect-sftp.out");
    //m_proc->setStandardErrorFile("/tmp/kdeconnect-sftp.err");
    connect(m_proc, &KProcess::readyReadStandardError, [this]() {
        qCDebug(KDECONNECT_PLUGIN_SFTP) << "stderr: " << m_proc->readAll();
    });
    connect(m_proc, &KProcess::readyReadStandardOutput, [this]() {
        qCDebug(KDECONNECT_PLUGIN_SFTP) << "stdout:" << m_proc->readAll();
    });
}
Example #13
0
void CShareManager::mountAutoShare(const QSharedPointer<SShare> &p)
{
	CShareSet::iterator it = prepared_.find(p);
	if(it == prepared_.end())
		return;
	try	{
		mounter_->mount(*(*it));
		emit mounted(mounter_->mountPoint() + (*it)->name);
		mounted_.insert(*it);
		prepared_.erase(it);
	}
	catch(CShareMounterInterface::CMountError &e)	{
		errors_.push_back( qMakePair(p, qMakePair(e.err(), QString(e.what()) ) ) );
		emit hasErrors();
	}
}
Example #14
0
int main(int argc, char **argv)
{
  parseArgs(argc,argv);
  if (mounted(Device)) {
    fprintf(stderr,"Won't make file system on mounted device.\n");
    exit(1);
  }
  buildSuperBlock();
  buildBitMaps();
  Disk = open(Device,O_RDWR);
  if (Check) checkBlocks();
  if (BBFile) loadBadBlockFile(BBFile);
  if (Verbose) {
    fprintf(stderr,"%d bad blocks found.\n",BadBlocks);
  }
  buildInodes();
  writeFS();
  close(Disk);
  return 0;
}
Example #15
0
Mounter::Mounter(SftpPlugin* sftp)
    : QObject(sftp)
    , m_sftp(sftp)
    , m_proc(nullptr)
    , m_mountPoint(sftp->mountPoint())
    , m_started(false)
{

    connect(m_sftp, SIGNAL(packageReceived(NetworkPackage)), this, SLOT(onPakcageReceived(NetworkPackage)));

    connect(&m_connectTimer, SIGNAL(timeout()), this, SLOT(onMountTimeout()));

    connect(this, SIGNAL(mounted()), &m_connectTimer, SLOT(stop()));
    connect(this, SIGNAL(failed(QString)), &m_connectTimer, SLOT(stop()));

    m_connectTimer.setInterval(10000);
    m_connectTimer.setSingleShot(true);

    QTimer::singleShot(0, this, SLOT(start()));
    qCDebug(KDECONNECT_PLUGIN_SFTP) << "Created mounter";
}
bool UDiskMountDevice::mount()
{
    if (mIsMounted)
        return true;

    QList<QVariant> args;
    args << QVariant(QString()) << QVariant(QStringList());

    bool ret;
    ret = mDbus->callWithCallback("FilesystemMount", args, this,
                             //SLOT(dbusSuccess(QDBusMessage)),
                             SIGNAL(mounted()),
                             SLOT(dbusError(QDBusError, QDBusMessage)));

    QStringList paths = mDbus->property("DeviceMountPaths").toStringList();

    if (!paths.empty())
        mMountPath = paths.at(0);
    else
        mMountPath = "";

    return ret;
}
Example #17
0
static int
prepare_mount(struct nilfs_mount_info *mi, const struct mount_options *mo)
{
	struct mntentchn *mc;
	gcpid_opt_t pid;
	pp_opt_t prot_period;
	int res = -1;

	if (!(mo->flags & MS_REMOUNT) && mounted(NULL, mi->mntdir)) {
		error(_("%s: %s is already mounted."), progname, mi->mntdir);
		goto failed;
	}

	mi->type = NORMAL_MOUNT;
	mi->gcpid = 0;
	mi->optstr = NULL;
	mi->mounted = mounted(mi->device, mi->mntdir);
	mi->protperiod = ULONG_MAX;

	if (mo->flags & MS_BIND)
		return 0;

	mc = find_rw_mount(mi->device);
	if (mc == NULL)
		return 0; /* no previous rw-mount */

	/* get the value of previous pp option if exists */
	prot_period = ULONG_MAX;
	if (find_opt(mc->m.mnt_opts, pp_opt_fmt, &prot_period) >= 0)
		mi->protperiod = prot_period;

	mi->nogc = (find_opt(mc->m.mnt_opts, nogc_opt_fmt, NULL) >= 0);

	switch (mo->flags & (MS_RDONLY | MS_REMOUNT)) {
	case 0: /* overlapping rw-mount */
		error(_("%s: the device already has a rw-mount on %s."
			"\n\t\tmultiple rw-mount is not allowed."),
		      progname, mc->m.mnt_dir);
		goto failed;
	case MS_RDONLY: /* ro-mount (a rw-mount exists) */
		break;
	case MS_REMOUNT | MS_RDONLY: /* rw->ro remount */
	case MS_REMOUNT: /* rw->rw remount */
		mi->type = (mo->flags & MS_RDONLY) ?
			RW2RO_REMOUNT : RW2RW_REMOUNT;

		if (check_remount_dir(mc, mi->mntdir) < 0)
			goto failed;
		pid = 0;
		if (find_opt(mc->m.mnt_opts, gcpid_opt_fmt, &pid) >= 0 &&
		    nilfs_shutdown_cleanerd(mi->device, (pid_t)pid) < 0) {
			error(_("%s: remount failed due to %s shutdown "
				"failure"), progname, NILFS_CLEANERD_NAME);
			goto failed;
		}
		mi->gcpid = pid;
		mi->optstr = xstrdup(mc->m.mnt_opts); /* previous opts */
		break;
	}

	res = 0;
 failed:
	return res;
}
Example #18
0
/*===========================================================================*
 *				do_close				     *
 *===========================================================================*/
PUBLIC int do_close()
{
/* Perform the close(fd) system call. */

  register struct filp *rfilp;
  register struct inode *rip;
  struct file_lock *flp;
  int rw, mode_word, lock_count;
  dev_t dev;

  /* First locate the inode that belongs to the file descriptor. */
  if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
  rip = rfilp->filp_ino;	/* 'rip' points to the inode */

  if (rfilp->filp_count - 1 == 0 && rfilp->filp_mode != FILP_CLOSED) {
	/* Check to see if the file is special. */
	mode_word = rip->i_mode & I_TYPE;
	if (mode_word == I_CHAR_SPECIAL || mode_word == I_BLOCK_SPECIAL) {
		dev = (dev_t) rip->i_zone[0];
		if (mode_word == I_BLOCK_SPECIAL)  {
			/* Invalidate cache entries unless special is mounted
			 * or ROOT
			 */
			if (!mounted(rip)) {
			        (void) do_sync();	/* purge cache */
				invalidate(dev);
			}    
		}
		/* Do any special processing on device close. */
		dev_close(dev);
	}
  }

  /* If the inode being closed is a pipe, release everyone hanging on it. */
  if (rip->i_pipe == I_PIPE) {
	rw = (rfilp->filp_mode & R_BIT ? WRITE : READ);
	release(rip, rw, NR_PROCS);
  }

  /* If a write has been done, the inode is already marked as DIRTY. */
  if (--rfilp->filp_count == 0) {
	if (rip->i_pipe == I_PIPE && rip->i_count > 1) {
		/* Save the file position in the i-node in case needed later.
		 * The read and write positions are saved separately.  The
		 * last 3 zones in the i-node are not used for (named) pipes.
		 */
		if (rfilp->filp_mode == R_BIT)
			rip->i_zone[V2_NR_DZONES+0] = (zone_t) rfilp->filp_pos;
		else
			rip->i_zone[V2_NR_DZONES+1] = (zone_t) rfilp->filp_pos;
	}
	put_inode(rip);
  }

  fp->fp_cloexec &= ~(1L << m_in.fd);	/* turn off close-on-exec bit */
  fp->fp_filp[m_in.fd] = NIL_FILP;
  FD_CLR(m_in.fd, &fp->fp_filp_inuse);

  /* Check to see if the file is locked.  If so, release all locks. */
  if (nr_locks == 0) return(OK);
  lock_count = nr_locks;	/* save count of locks */
  for (flp = &file_lock[0]; flp < &file_lock[NR_LOCKS]; flp++) {
	if (flp->lock_type == 0) continue;	/* slot not in use */
	if (flp->lock_inode == rip && flp->lock_pid == fp->fp_pid) {
		flp->lock_type = 0;
		nr_locks--;
	}
  }
  if (nr_locks < lock_count) lock_revive();	/* lock released */
  return(OK);
}
Example #19
0
static

#endif

char*
pathreal(const char* apath, register int type, struct stat* st)
{
	char*			path = (char*)apath;
	register char*		sp;
	register char*		cp;
	register char*		ip;
	Table_t*		safe;
	int			oerrno = errno;
	int			opaqued = 0;
	int			len;
	int			vir;
	int			safesize;
	int			safe_dir;
	long			visits;
	char			buf[PATH_MAX + 1];

	static struct stat	stbuf;
	static struct stat	tsbuf;

	state.path.level = state.path.synthesize = state.path.nlinks = 0;
	if (!path)
	{
		errno = EFAULT;
		return 0;
	}
	initialize();
	if (state.in_2d)
	{
		if (!st || (!state.level || *path == '/') && !LSTAT(path, st))
			return path;
		if (state.level && streq(path, ".") && !CHDIR(state.pwd))
		{
			state.level = 0;
			return path;
		}
		return 0;
	}
#if FS
	if (mounted() && (sp = fsreal(state.path.monitor, MSG_stat, state.path.mount)))
		apath = (char*)(path = sp);
#endif

	/*
	 * handle null path, . and / separately
	 */

	if (safe = state.safe ? &state.vsafe : (Table_t*)0)
	{
		type |= P_ABSOLUTE;
		if (!(safesize = state.safe->servicesize))
			safesize = strlen(state.safe->service);
	}
	else
		type &= ~P_SAFE;
 again:
	if (!*path)
	{
		errno = ENOENT;
		return 0;
	}
	cp = sp = path;
	state.path.synthesize = state.path.linksize = 0;
	if (!st)
		st = &stbuf;

	/*
	 * check if virtual dir has been created by another process
	 * only P_PATHONLY|P_TOP calls (usually create or modify link) and
	 * references to "." are checked for performance
	 */

	if (state.level > 0 && state.pwd && ((type & (P_PATHONLY|P_TOP)) && *sp != '/' || *sp == '.' && sp[1] == 0))
	{
		if (!CHDIR(state.pwd))
			state.level = 0;
		else if (!(type & (P_PATHONLY|P_TOP)))
		{
			len = 0;
			state.path.level += (state.path.synthesize = state.level);
			sp = strcpy(state.path.name, state.pwd);
			goto skip;
		}
	}
	if (!state.pwd || sp[1] == 0 && (*sp == '.' || *sp == '/' && !safe))
	{
		if (st != &stbuf && LSTAT(sp, st))
			return 0;
		if (*sp == '/' || !state.pwd && (type & P_PATHONLY))
			strncpy(state.path.name, sp, PATH_MAX);
		else if (!state.pwd)
		{
			/*
			 * treat the current directory as if were empty
			 */

			errno = ENOENT;
			return 0;
		}
		else
			strncpy(state.path.name, state.pwd, PATH_MAX);
		errno = oerrno;
		return state.path.name;
	}

	/*
	 * put absolute pathname into state.path
	 */

	safe_dir = 0;
	if (*path != '/')
	{
		strcpy(state.path.name, state.pwd);
		sp = state.path.name + state.pwdsize;
		*sp++ = '/';
		if (safe && state.pwdsize >= safesize && !strncmp(state.pwd, state.safe->service, safesize) && (!state.pwd[safesize] || state.pwd[safesize] == '/'))
			safe_dir = safesize;
	}
	else
		sp = state.path.name;
	ip = state.path.name + elementsof(state.path.name);
	while (sp < ip && (*sp = *cp++))
		sp++;
	if (type & P_DOTDOT)
		strcpy(sp, "/..");
	sp = state.path.name;
	if (!(ip = pathcanon(sp + safe_dir, sizeof(state.path.name) - safe_dir, 0)))
	{
		errno = ENOENT;
		return 0;
	}
	if (type & (P_DOTDOT|P_NOSLASH))
	{
		/*
		 * remove trailing slashes
		 */

		while (*--ip == '/');
		*++ip = 0;
	}
	else if ((type & P_SLASH) && *(ip - 1) != '/')
		*ip++ = '/';
	if (*(ip - 1) == '/' && ip - sp > 1)
	{
		/*
		 * trailing slash is equivalent to trailing slash-dot
		 * this forces the common-sense interpretation
		 */
#if DEBUG
		if (!(state.test & 010))
#endif
		*ip++ = '.';
		*ip = 0;
	}
	len = ip - sp;

	/*
	 * try to use relative path
	 */

	if (!(type & (P_LSTAT|P_READLINK)))
	{
		for (ip = state.pwd; *ip && *ip == *sp++; ip++);
		if (*ip != 0 || *sp && *sp != '/' || state.level < 0)
			sp = state.path.name;
		else
		{
			state.path.level += (state.path.synthesize = state.level);
			if (state.level && !(type & P_PATHONLY) && st == &stbuf)
			{
				sp = state.path.name;
				len -= state.pwdsize;
			}
			else if (type & P_ABSOLUTE)
				sp = state.path.name;
			else if (*sp == '/')
				sp++;
		}
		if (*sp == 0)
			sp = state.dot;
	}
 skip:
	if ((type & P_NOOPAQUE) && !LSTAT(sp, st) && checkopaque(sp, st))
	{
		message((-1, "%s: remove opaque", sp));
		UNLINK(sp);
		opaqued = 1;
	}
	if (safe && *sp == '/')
	{
		state.path.table = safe;
		cp = pathnext(sp, NiL, NiL);
		state.path.table = safe = 0;
		if (cp)
		{
			state.path.level = 0;
			path = strcpy(buf, sp);
			message((-5, "pathreal: == safe map %s", path));
			type &= ~(P_DOTDOT|P_SAFE);
			goto again;
		}
		if (!*(sp + 1))
		{
			strncpy(sp, state.safe->service, safesize);
			sp[safesize] = 0;
		}
		else if (strncmp(sp, state.safe->service, safesize) || sp[safesize] && sp[safesize] != '/')
		{
			if (*path != '/' && safe_dir)
			{
				errno = EPERM;
				return 0;
			}
			if (sp[1])
				strcpy(buf, sp);
			else
				*buf = 0;
			len = sfsprintf(sp, sizeof(state.path.name), "%-*s%s", safesize, state.safe->service, buf);
			message((-5, "pathreal: == safe next %s", sp));
			if (!pathnext(sp, NiL, NiL))
			{
				errno = EPERM;
				return 0;
			}
		}
		else
			type &= ~P_SAFE;
	}
	if ((type & P_SAFE) && state.path.level)
	{
		errno = EPERM;
		return 0;
	}
	if (type & P_PATHONLY)
	{
		errno = oerrno;
		return sp;
	}
	visits = 0;
	vir = 1;
	while (LSTAT(sp, st))
	{
		if (vir)
		{
			if (apath[0] == '.' && apath[1] == '.' && apath[2] == '.' && !apath[3])
			{
				if (state.level > 0)
				{
					message((-1, "pathreal: %s => %s", apath, sp));
					LSTAT(".", st);
					return sp;
				}
				errno = ENOENT;
				return 0;
			}
			vir = 0;
		}
		if (errno == ENOTDIR)
		{
			/*
			 * check for version instance
			 */

			cp = ip = sp + strlen(sp);
			while (ip > sp && *--ip != '/');
			if (ip < sp)
				return 0;
			while (ip > sp && *--ip == '/');
			if (ip < sp)
				return 0;
			while (ip > sp && *--ip != '/');
			if (*ip == '/')
				ip++;
			while (cp >= ip)
			{
				cp[4] = *cp;
				cp--;
			}
			memcpy(ip, state.opaque, 4);
			if (!LSTAT(sp, st))
				break;
			errno = ENOTDIR;
			return 0;
		}

		if (errno != ENOENT || opaqued)
			return 0;
#if FS
		/*
		 * check user mount
		 */

		if (visits)
		{
			Mount_t*	mp;
			const char*	up;

			if ((mp = getmount(sp, &up)) && (mp->fs->flags & FS_NAME) && (sp = fsreal(mp, MSG_open, (char*)up)) && !LSTAT(sp, st))
				break;
		}
#endif

		/*
		 * search down the viewpath
		 */

		if (type & P_SAFE)
		{
			errno = EPERM;
			return 0;
		}
		if (!pathnext(state.path.name, NiL, &visits))
			return 0;
		sp = state.path.name;
		if (!(type & P_ABSOLUTE))
		{
			/*
			 * try to use relative path
			 */

			for (ip = state.pwd; *ip && *ip == *sp++; ip++);
			if (*ip == 0 && *sp == '/')
				sp++;
			else
				sp = state.path.name;
		}
		if (*sp == 0)
			sp = state.dot;
	}
	if (st->st_nlink > 1 && checkopaque(sp, st))
		return 0;
	if ((type & P_TOP) && state.path.level)
	{
		int	rfd;
		int	wfd;

		if ((rfd = OPEN(sp, O_RDONLY, 0)) < 0)
			sp = 0;
		else
		{
			tsbuf = *st;
			wfd = open(apath, O_WRONLY|O_CREAT|O_TRUNC|O_cloexec, st->st_mode & S_IPERM);
			*st = tsbuf;
			if (wfd < 0)
				sp = 0;
			else 
			{
				if (fs3d_copy(rfd, wfd, st))
					sp = 0;
				CLOSE(wfd);
			}
			CLOSE(rfd);
		}
		if (!sp)
		{
			errno = EROFS;
			return 0;
		}
		if (st == &stbuf)
			st = 0;
		return pathreal(apath, P_PATHONLY, st);
	}
	IVIEW(st, state.path.level);
	if (state.path.synthesize)
	{
		if (state.path.level < state.level)
		{
			if (len)
			{
				ip  = state.path.name + strlen(state.path.name) - len;
				len = *ip;
				*ip = 0;
			}
			if (!CHDIR(state.path.name))
				state.level = state.path.level;
			message((-1, "chdir=%s level=%d", state.path.name, state.level));
			*ip = len;
		}
		else if (S_ISDIR(st->st_mode))
		{
			int		mask;
			static int	uid = -1;
			static int	gid;

			umask(mask = umask(0));
			st->st_mode = (st->st_mode | (S_IRWXU|S_IRWXG|S_IRWXO)) & ~(mask & (S_IRWXU|S_IRWXG|S_IRWXO));
			if (uid == -1)
			{
				uid = geteuid();
				gid = getegid();
			}
			st->st_uid = uid;
			st->st_gid = gid;
		}
	}
	ip = sp;

	/*
	 * symbolic links handled specially
	 * get filename from pathname
	 */

	if (S_ISLNK(st->st_mode) && (len = checklink(sp, st, type)) > 1 && !(type & (P_LSTAT|P_READLINK)) && state.path.nlinks++ < MAXSYMLINKS)
	{
		path = strcpy(buf, state.path.name);
		message((-1, "pathreal: == again %s", path));
		if (*path != '/')
			state.path.level = 0;
		type &= ~(P_DOTDOT|P_SAFE);
		goto again;
	}
#if VCS && defined(VCS_REAL)
	VCS_REAL(state.path.name, st);
#endif
	errno = oerrno;
	return sp;
}
Example #20
0
	// if r == null, means unmount
	void SubVfs::setRoot(RootFs* r) { 
        AIO_PRE_CONDITION(!mounted() || r == 0);
        m_root = r;
	}
Example #21
0
int
main(int argc, char *argv[])
{
	char *types = NULL, data[512] = "", *resolvpath = NULL;
	char *files[] = { "/proc/mounts", "/etc/fstab", NULL };
	const char *source, *target;
	struct mntent *me = NULL;
	int aflag = 0, oflag = 0, status = 0, i, r;
	unsigned long flags = 0;
	FILE *fp;

	ARGBEGIN {
	case 'B':
		argflags |= MS_BIND;
		break;
	case 'M':
		argflags |= MS_MOVE;
		break;
	case 'R':
		argflags |= MS_REC;
		break;
	case 'a':
		aflag = 1;
		break;
	case 'o':
		oflag = 1;
		argopts = EARGF(usage());
		parseopts(argopts, &flags, data, sizeof(data));
		break;
	case 't':
		types = EARGF(usage());
		break;
	case 'n':
		break;
	default:
		usage();
	} ARGEND;

	if (argc < 1 && aflag == 0) {
		if (!(fp = fopen(files[0], "r")))
			eprintf("fopen %s:", files[0]);
		concat(fp, files[0], stdout, "<stdout>");
		fclose(fp);
		return 0;
	}

	if (aflag == 1)
		goto mountall;

	source = argv[0];
	target = argv[1];

	if (!target) {
		target = argv[0];
		source = NULL;
		if (!(resolvpath = realpath(target, NULL)))
			eprintf("realpath %s:", target);
		target = resolvpath;
	}

	for (i = 0; files[i]; i++) {
		if (!(fp = setmntent(files[i], "r"))) {
			if (strcmp(files[i], "/proc/mounts") != 0)
				weprintf("setmntent %s:", files[i]);
			continue;
		}
		while ((me = getmntent(fp))) {
			if (strcmp(me->mnt_dir, target) == 0 ||
			   strcmp(me->mnt_fsname, target) == 0 ||
			   (source && strcmp(me->mnt_dir, source) == 0) ||
			   (source && strcmp(me->mnt_fsname, source) == 0)) {
				if (!source) {
					target = me->mnt_dir;
					source = me->mnt_fsname;
				}
				if (!oflag)
					parseopts(me->mnt_opts, &flags, data, sizeof(data));
				if (!types)
					types = me->mnt_type;
				goto mountsingle;
			}
		}
		endmntent(fp);
		fp = NULL;
	}
	if (!source)
		eprintf("can't find %s in /etc/fstab\n", target);

mountsingle:
	r = mounthelper(source, target, types);
	if (r == -1)
		status = 1;
	if (r > 0 && mount(source, target, types, argflags | flags, data) < 0) {
		weprintf("mount: %s:", source);
		status = 1;
	}
	if (fp)
		endmntent(fp);
	free(resolvpath);
	return status;

mountall:
	if (!(fp = setmntent("/etc/fstab", "r")))
		eprintf("setmntent %s:", "/etc/fstab");
	while ((me = getmntent(fp))) {
		/* has "noauto" option or already mounted: skip */
		if (hasmntopt(me, MNTOPT_NOAUTO) || mounted(me->mnt_dir))
			continue;
		flags = 0;
		parseopts(me->mnt_opts, &flags, data, sizeof(data));
		/* if -t types specified:
		 * if non-match, skip
		 * if match and prefixed with "no", skip */
		if (types &&
		    ((types[0] == 'n' && types[1] == 'o' &&
		     findtype(types + 2, me->mnt_type)) ||
		     (!findtype(types, me->mnt_type))))
			continue;

		r = mounthelper(me->mnt_fsname, me->mnt_dir, me->mnt_type);
		if (r > 0 && mount(me->mnt_fsname, me->mnt_dir, me->mnt_type,
		                   argflags | flags, data) < 0) {
			weprintf("mount: %s:", me->mnt_fsname);
			status = 1;
		}
	}
	endmntent(fp);

	return status;
}