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

📄 devcon.c.svn-base

📁 SFS是一个完全分散控制的的网路档案系统。sfslite 用于简化事件驱动网络编程的有用组件。
💻 SVN-BASE
字号:
/* $Id$ *//* * * Copyright (C) 1999 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 "sfs-internal.h"#include "hashtab.h"#include "sfsagent.h"const char *path_suidconnect;const char *path_devdb;static pid_t sfspid;static struct timespec devdb_mtime;struct dev_prog {  u_int64_t dev;  char *prog;  char *fs;  struct hashtab_entry link;};hashtab_decl (dev2prog, dev_prog, link) devtab;struct prog_fd {  char *prog;  int fd;  struct hashtab_entry link;};hashtab_decl (prog2fd, prog_fd, link) progtab;static voidset_paths (void){#ifdef MAINTAINER  const char *builddir = getenv ("SFS_RUNINPLACE");  const char *rootdir = getenv ("SFS_ROOT");#endif /* MAINTAINER */  if (!path_suidconnect) {#ifdef MAINTAINER    static const char scpath[] = "/libsfs/suidconnect";    if (builddir) {      char *buf = malloc (strlen (builddir) + sizeof (scpath));      assert (buf);      strcpy (buf, builddir);      strcat (buf, scpath);      path_suidconnect = buf;    }    else#endif /* MAINTAINER */      path_suidconnect = EXECDIR "/suidconnect";  }  if (!path_devdb) {#ifdef MAINTAINER    static const char ddbpath[] = "/.devdb";    if (rootdir) {      char *buf = malloc (strlen (rootdir) + sizeof (ddbpath));      assert (buf);      strcpy (buf, rootdir);      strcat (buf, ddbpath);      path_devdb = buf;    }    else#endif /* MAINTAINER */      path_devdb = "/sfs/.devdb";  }}static intrecvfd (int fd){  int nfd = -1;  char c;  readfd (fd, &c, 1, &nfd);  return nfd;}static intsuidgetfd (const char *prog){  int fds[2];  int nfd;  char *av[3] = { "suidconnect", (char *) prog, NULL };  if (!path_suidconnect)    set_paths ();  if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0) {    perror ("socketpair");    return -1;  }  switch (fork ()) {  case -1:    perror ("fork");    close (fds[0]);    close (fds[1]);    return -1;  case 0:    close (fds[1]);    if (fds[0]) {      dup2 (fds[0], 0);      close (fds[0]);    }    execv (path_suidconnect, av);    perror (path_suidconnect);	/* XXX */    exit (1);  }  close (fds[0]);  nfd = recvfd (fds[1]);  close (fds[1]);  return nfd;}static intgetprogfd (const char *prog){  int fd;  int pid;  int flags;  enum clnt_stat err;  fd = suidgetfd (prog);  if (fd < 0)    return -1;  flags = fcntl (fd, F_GETFL, 0);  if (flags == -1) {    close (fd);    return -1;  }  flags &= ~O_NONBLOCK;  fcntl (fd, F_SETFL, flags);  pid = getpid ();  err = srpc_call (&sfsctl_prog_1, fd, SFSCTL_SETPID, &pid, NULL);  if (err) {    clnt_perrno (err);		/* XXX */    close (fd);    return -1;  }  return fd;}static voiddev2str (char *out, u_int64_t dev){  if (dev >= INT64 (0x100000000))    sprintf (out, "0x%x%08x", (int) (dev >> 32), (int) (dev & 0xffffffffU));  else    sprintf (out, "0x%x", (int) (dev & 0xffffffffU));}static bool_tdevdblookup (char **progp, char **fsp, u_int64_t dev){  char linebuf[512];  char devstr[20];  size_t devlen;  FILE *ddbf;  if (!path_devdb)    set_paths ();  if (progp)    *progp = NULL;  if (fsp)    *fsp = NULL;  dev2str (devstr, dev);  strcat (devstr, " ");  devlen = strlen (devstr);  ddbf = fopen (path_devdb, "r");  if (!ddbf)    return FALSE;  while (fgets (linebuf, sizeof (linebuf), ddbf))    if (!strncmp (linebuf, devstr, devlen)) {      char *sdev, *sfs, *sprog;      char *bufp = linebuf;      if ((sdev = strnnsep_c (&bufp, " \r\n"))	  && (sfs = strnnsep_c (&bufp, " \r\n")) && strlen (sfs) <= 255	  && (sprog = strnnsep_c (&bufp, " \r\n")) && strlen (sprog) <= 255) {	if (fsp) {	  *fsp = malloc (strlen (sfs) + 1);	  if (!*fsp) {	    fclose (ddbf);	    return FALSE;	  }	  strcpy (*fsp, sfs);	}	if (progp) {	  *progp = malloc (strlen (sprog) + 1);	  if (!*progp) {	    if (fsp) {	      free (*fsp);	      *fsp = NULL;	    }	    fclose (ddbf);	    return FALSE;	  }	  strcpy (*progp, sprog);	}	fclose (ddbf);	return TRUE;      }    }  fclose (ddbf);  return FALSE;}static voiddeldpp (void *_null, struct dev_prog *dpp){  dev2prog_delete (&devtab, dpp);  free (dpp->prog);  free (dpp->fs);  free (dpp);}static struct dev_prog *getdpp (u_int64_t dev){  struct dev_prog *dpp;  for (dpp = dev2prog_chain (&devtab, dev); dpp && dpp->dev != dev;       dpp = dev2prog_next (dpp))    ;  if (dpp)    return dpp;  dpp = malloc (sizeof (*dpp));  if (!dpp)    return NULL;  dpp->dev = dev;  devdblookup (&dpp->prog, &dpp->fs, dev);  dev2prog_insert (&devtab, dpp, dev);  return dpp;}static voiddelpfp (void *_null, struct prog_fd *pfp){  prog2fd_delete (&progtab, pfp);  free (pfp->prog);  if (pfp->fd >= 0)    close (pfp->fd);  free (pfp);}static struct prog_fd *getpfp (const char *prog){  u_int hval = hash_string (prog);  struct prog_fd *pfp;  for (pfp = prog2fd_chain (&progtab, hval); pfp && strcmp (prog, pfp->prog);       pfp = prog2fd_next (pfp))    ;  if (pfp)    return pfp;  pfp = malloc (sizeof (*pfp));  if (!pfp)    return NULL;  pfp->fd = getprogfd (prog);  pfp->prog = malloc (strlen (prog) + 1);  if (!pfp->prog) {    free (pfp);    return NULL;  }  strcpy (pfp->prog, prog);  prog2fd_insert (&progtab, pfp, hval);  return pfp;}voiddevcon_flush (void){  dev2prog_traverse (&devtab, deldpp, NULL);  sfs_flush_idcache ();}voiddevcon_close (void){  dev2prog_traverse (&devtab, deldpp, NULL);  prog2fd_traverse (&progtab, delpfp, NULL);  sfs_flush_idcache ();}static voiddevcon_ckfresh (void){  pid_t mypid;  struct stat sb;  mypid = getpid ();  if (sfspid != mypid) {    sfspid = mypid;    prog2fd_traverse (&progtab, delpfp, NULL);  }  if (!path_devdb)    set_paths ();  if (stat (path_devdb, &sb) >= 0) {    struct timespec mtime;#ifdef SFS_HAVE_STAT_ST_MTIMESPEC    mtime = sb.st_mtimespec;#else /* !SFS_HAVE_STAT_ST_MTIMESPEC */    mtime.tv_sec = sb.st_mtime;    mtime.tv_nsec = 0;#endif /* !SFS_HAVE_STAT_ST_MTIMESPEC */    if (mtime.tv_sec != devdb_mtime.tv_sec	|| mtime.tv_nsec != devdb_mtime.tv_nsec) {      devdb_mtime = mtime;      dev2prog_traverse (&devtab, deldpp, NULL);    }  }}bool_tdevcon_lookup (int *fdp, const char **fsp, dev_t dev){  struct dev_prog *dpp;  struct prog_fd *pfp;  devcon_ckfresh ();  *fdp = -1;  *fsp = NULL;  dpp = getdpp (dev2int (dev));  if (!dpp || !dpp->prog || !dpp->fs)    return FALSE;  *fsp = dpp->fs;  pfp = getpfp (dpp->prog);  if (!pfp || pfp->fd < 0)    return FALSE;  *fdp = pfp->fd;  return TRUE;}

⌨️ 快捷键说明

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