⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adm.c

📁 A part of LFS.This is a server software.
💻 C
字号:
/* $Id: adm.C,v 1.6 2001/09/20 06:21:25 dm Exp $ *//* * * Copyright (C) 2001 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */#include "getfh3.h"#include "classfs_prot.h"#include "nfsmounter.h"#include "classfsd.h"#include "rxx.h"int ping_timeout = 600;class cfsadm;qhash<str, ref<cfsadm> > &fstab = *New qhash<str, ref<cfsadm> >;ptr<asrv> rootsrv;AUTH *myauth = authunix_create_realids ();struct pinger {  const sockaddr_in sin;  cfsadm *const cfsp;  time_t lastping;  timecb_t *wait;  callbase *cbase;  pinger (cfsadm *cfsp, const sockaddr_in &sin);  ~pinger ();  void pinged (clnt_stat stat);  void waitcb ();};class cfsadm : public virtual refcount {  authunix_parms *aup;  ptr <axprt_unix> x;  ptr <asrv> s;  void mount (svccb *sbp);  void mounted (svccb *sbp, ref<mountres> resp, sockaddr_in sin,		clnt_stat err);  void dispatch (svccb *sbp);protected:  cfsadm (ref<axprt_unix> x, const authunix_parms *aup);  PRIVDEST ~cfsadm ();public:  qhash<str, ref<pinger> > mps;  void kill () { if (x) dispatch (NULL); }  static void alloc (ptr<axprt_unix> x, const authunix_parms *aup)    { if (x) vNew refcounted<cfsadm> (x, aup); }};pinger::pinger (cfsadm *c, const sockaddr_in &s)    : sin (s), cfsp (c), wait (NULL), cbase (NULL){  pinged (RPC_SUCCESS);}pinger::~pinger (){  timecb_remove (wait);  if (cbase)    cbase->cancel ();}voidpinger::pinged (clnt_stat stat){  cbase = NULL;  if (!stat)    lastping = timenow;  if (ping_timeout && timenow > lastping + ping_timeout)    cfsp->kill  ();  else    wait = delaycb (60, wrap (this, &pinger::waitcb));}voidpinger::waitcb (){  wait = NULL;  cbase = udpclnt->call (NFSPROC3_NULL, NULL, NULL,			 wrap (this, &pinger::pinged), myauth,			 xdr_void, xdr_void,			 nfs_program_3.progno, nfs_program_3.versno,			 (sockaddr *) &sin);}cfsadm::cfsadm (ref<axprt_unix> xx, const authunix_parms *au)  : x (xx), s (asrv::alloc (x, classfs_prog_1, wrap (this, &cfsadm::dispatch))){  x->allow_recvfd = true;  aup = static_cast<authunix_parms *> (xmalloc (sizeof (*aup)));  *aup = *au;  *reinterpret_cast<void **> (&aup->aup_gids)    = xmalloc (aup->aup_len * sizeof (aup->aup_gids[0]));  memcpy (aup->aup_gids, au->aup_gids,	  aup->aup_len * sizeof (aup->aup_gids[0]));  aup->aup_machname = "localhost";  refcount_inc ();}cfsadm::~cfsadm (){  xfree (aup->aup_gids);  xfree (aup);}voidcfsadm::mount (svccb *sbp){  static rxx nameok ("\\w[\\w\\.\\-]*");  classfs_mount_arg *arg = sbp->template getarg<classfs_mount_arg> ();  int fd = x->recvfd ();  if (fd < 0) {    sbp->replyref (EBADF);    return;  }  sockaddr_in sin;  socklen_t len = sizeof (sin);  if (getsockname (fd, (sockaddr *) &sin, &len) < 0) {    close (fd);    sbp->replyref (ENOTSOCK);    return;  }  int n;  len = sizeof (n);  if (sin.sin_family != AF_INET      || getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &n, &len) < 0      || n != SOCK_DGRAM) {    close (fd);    sbp->replyref (ESOCKTNOSUPPORT);    return;  }  if (!nameok.match (arg->name)) {    close (fd);    sbp->replyref (EINVAL);    return;  }  if (!uid_mkdir (aup2aid (aup), arg->name)) {    close (fd);    sbp->replyref (EEXIST);    return;  }  // uid_rmdir (aup2aid (aup), arg->name);  mountarg ma;  ma.hostname = strbuf () << "*" << aup2aid (aup) << "!" << arg->name;  ma.path = mountpoint (aup, arg->name);  ma.flags = NMOPT_NFS3|NMOPT_SOFT;  ma.handle = arg->fh;  ref<mountres> mrp (New refcounted<mountres>);  nmx->sendfd (fd);  nmc->call (NFSMOUNTER_MOUNT, &ma, mrp,	     wrap (mkref(this), &cfsadm::mounted, sbp, mrp, sin));}voidcfsadm::mounted (svccb *sbp, ref<mountres> resp, sockaddr_in sin,		 clnt_stat err){  classfs_mount_arg *arg = sbp->template getarg<classfs_mount_arg> ();  if (err)    fatal << "nfsmounter: " << err << "\n";  if (resp->status) {    uid_rmdir (aup2aid (aup), arg->name);    warn << "*" << aup2aid (aup) << "!" << arg->name	 << ": " << strerror (resp->status) << "\n";  }  else {    str mp = mountpoint (aup, arg->name);    mps.insert (mp, New refcounted<pinger> (this, sin));    fstab.insert (mp, mkref (this));  }  sbp->replyref (resp->status);}voidcfsadm::dispatch (svccb *sbp){  if (!sbp) {    if (x) {      sfs_aid aid = aup2aid (aup);      warn << "EOF from aid " << aid << "\n";      s = NULL;      x = NULL;      qhash_slot<str, ref<pinger> > *sp, *nsp;      for (sp = mps.first (); sp; sp = nsp) {	static rxx basenamerx ("[^/]*$");	nsp = mps.next (sp);	basenamerx.search (sp->key);	warn << "unmounting " << basenamerx[0] << "\n";	detach (aid, basenamerx[0]);      }      refcount_dec ();    }    return;  }  switch (sbp->proc ()) {  case CLASSFSPROC_NULL:    sbp->reply (NULL);    break;  case CLASSFSPROC_MOUNT:    mount (sbp);    break;  default:    sbp->reject (PROC_UNAVAIL);    break;  }}static void unmount_send (sfs_aid aid, str name, bool logit);static voidunmount_cb (sfs_aid aid, str name, ref<int> res, clnt_stat err){  if (err)    fatal << "nfsmounter: " << err << "\n";  if (*res)    delaycb (5, wrap (unmount_send, aid, name, false));  else    uid_rmdir (aid, name);}static voidunmount_send (sfs_aid aid, str name, bool logit){  umountarg arg;  arg.path = mountpoint (aid, name);  if (logit)    arg.flags = NUOPT_FORCE|NUOPT_STALE;  else    arg.flags = NUOPT_FORCE|NUOPT_STALE|NUOPT_NLOG;  ref<int> res = New refcounted<int> (EBUSY);  nmc->call (NFSMOUNTER_UMOUNT, &arg, res, wrap (unmount_cb, aid, name, res));}boolkillserv (sfs_aid aid, str name){  str fsname = mountpoint (aid, name);  cfsadm *cfsp = fstab[fsname];  if (!cfsp)    return false;  cfsp->kill ();  return true;}booldetach (sfs_aid aid, str name){  str fsname = mountpoint (aid, name);  cfsadm *cfsp = fstab[fsname];  if (!cfsp)    return false;  cfsp->mps.remove (fsname);  fstab.remove (fsname);  rootdir->aidunlink (aid, name);  unmount_send (aid, name, true);  return true;}static voidadm_mounted (ref<mountres> resp, clnt_stat err){  if (err)    fatal << "nfsmounter: " << err << "\n";  if (resp->status)    fatal << mntpath << ": " << strerror (resp->status) << "\n";  sfs_suidserv ("classfs", wrap (&cfsadm::alloc));}voidadm_init (void){  int nfsfd = inetsocket (SOCK_DGRAM, 0, INADDR_LOOPBACK);  rootsrv = asrv::alloc (axprt_dgram::alloc (nfsfd), nfs_program_3,			 wrap (&afsnode::dispatch3));  nfs_fh3 fh;  rootdir->mkfh3 (&fh);  mountarg arg;  arg.hostname = strbuf ("(%s)", progname.cstr ());  arg.path = mntpath;  arg.flags = NMOPT_NFS3|NMOPT_SOFT|NMOPT_NOAC;  arg.handle.set (const_cast<char *> (fh.data.base ()), fh.data.size ());  ref<mountres> mrp (New refcounted<mountres>);  nmx->sendfd (nfsfd, false);  nmc->call (NFSMOUNTER_MOUNT, &arg, mrp, wrap (adm_mounted, mrp));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -