Пример #1
0
static int
lua_cwd(lua_State *L)
{
#ifdef _WIN32

  char drv[2];
  int l;
  SB sb;
  sbinit(&sb);
  drv[0] = '.'; drv[1] = 0;
  l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
  if (l > sb.maxlen) {
    sbgrow(&sb, l+1);
    l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
  }
  if (l <= 0)
    return sbsetpush(L, &sb, ".");
  sb.len += l;
  return sbpush(L, &sb);

#elif HAVE_GETCWD
  
  const char *s;
  SB sb;
  sbinit(&sb);
  s = getcwd(sb.buffer, sb.maxlen);
  while (!s && errno==ERANGE)
    {
      sbgrow(&sb, sb.maxlen + SBINCREMENT);
      s = getcwd(sb.buffer, sb.maxlen);
    }
  if (! s)
    return sbsetpush(L, &sb, ".");
  sb.len += strlen(s);
  return sbpush(L, &sb);

#else
  
  const char *s;
  SB sb;
  sbinit(&sb);
  sbgrow(&sb, PATH_MAX); 
  s = getwd(sb.buffer);
  if (! s)
    return sbsetpush(L, &sb, ".");
  sb.len += strlen(s);
  return sbpush(L, &sb);

#endif
}
Пример #2
0
static const char *
executable_dir(const char *progname)
{
  SB sb;
  struct stat sbuf;
  if (! progname)
    return 0;
  sbinit(&sb);
  if (progname[0]=='/')
    sbaddn(&sb, progname, strlen(progname));
  else if (strchr(progname,'/'))
    sbaddsf(&sb,catpath(NULL,progname));
  else {
    char *p = getenv("PATH");
    for (;;) {
      sb.len = 0;
      if (! (p && *p))
        return sbfree(&sb);
      while (*p && *p!=':')
        sbadd1(&sb, *p++);
      if (*p ==':')
        p++;
      sbadd1(&sb, 0);
      sb.len = 0;
      sbaddsf(&sb, catpath(sb.buffer, progname));
      sbadd1(&sb, 0);
      if (sb.buffer && stat(sb.buffer,&sbuf)>=0 && S_ISREG(sbuf.st_mode))
        if (access(sb.buffer, X_OK) >= 0)
          break;
    }
  }
#ifdef S_ISLNK
  sbadd1(&sb, 0);
  while(sb.buffer && lstat(sb.buffer,&sbuf)>=0 && S_ISLNK(sbuf.st_mode))
    {
      int h,l;
      sbaddn(&sb,"../",3);
      h = sb.len;
      while ((l=readlink(sb.buffer,sb.buffer+h,sb.maxlen-h))>=sb.maxlen-h)
        sbgrow(&sb, sb.maxlen - h + SBINCREMENT);
      if (l < 0)
        return sbfree(&sb);
      sb.len = h + l;
      sbadd1(&sb,0);
      sb.len = 0;
      sbaddsf(&sb, catpath(sb.buffer,sb.buffer+h-3));
      sbadd1(&sb,0);
    }
#endif
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
    sb.len -= 1;
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/')
    sb.len -= 1;
  while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
    sb.len -= 1;
  sbadd1(&sb, 0);
  return sb.buffer;
}
Пример #3
0
static char *
catpath(const char *from, const char *fname)
{
  SB sb;
  sbinit(&sb);
  if (fname && fname[0]=='/') 
    sbadd1(&sb, '/');
  else if (from)
    sbaddsf(&sb, catpath(NULL,from));
  else {
    char *cwd = 0;
    while (sb.buffer && !cwd) {
      cwd = getcwd(sb.buffer + sb.len, sb.maxlen - sb.len);
      if (cwd || errno != ERANGE) break;
      sbgrow(&sb, sb.maxlen - sb.len + SBINCREMENT);
    }
    if (cwd)
      sb.len += strlen(cwd);
    else
      sbfree(&sb);
  }
  for (;;) {
    while (fname && fname[0]=='/')
      fname++;
    if (!fname || !fname[0]) {
      while (&sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
        sb.len -= 1;
      sbadd1(&sb, 0);
      return sb.buffer;
    }
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]==0) {
        fname +=1;
        continue;
      }
      if (fname[1]=='.')
        if (fname[2]=='/' || fname[2]==0) {
          fname +=2;
          while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]=='/')
            sb.len -= 1;
          while (sb.buffer && sb.len>0 && sb.buffer[sb.len-1]!='/')
            sb.len -= 1;
          continue;
        }
    }
    if (sb.len==0 || (sb.buffer && sb.buffer[sb.len-1]!='/'))
      sbadd1(&sb, '/');
    while (*fname!=0 && *fname!='/')
      sbadd1(&sb, *fname++);
  }
  sbadd1(&sb, 0);
  return sb.buffer;
}
Пример #4
0
static char *concatargs(int cargc, char **cargv) {
  static char bigbuf[1024];
  StringBuf b;
  int i;

  sbinit(&b, bigbuf, sizeof(bigbuf));
  for(i=0;i<cargc;i++) {
    sbaddstr(&b, cargv[i]);
    sbaddchar(&b, ' ');
  }
  sbterminate(&b);

  return bigbuf;
}
Пример #5
0
int
ncp_sock_recv(struct socket *so, struct sockbuf *sio)
{
	int error, flags;

	sbinit(sio, 1000000);	/* limit data returned (inexact, hint only) */
	flags = MSG_DONTWAIT;

	error = so_pru_soreceive(so, NULL, NULL, sio, NULL, &flags);
#ifdef NCP_SOCKET_DEBUG
	if (error)
		kprintf("ncp_recv: err=%d\n", error);
#endif
	return (error);
}
Пример #6
0
static int dbapi2_adapter_quotestring(const DBAPIConn *db, char *buf, size_t buflen, const char *data, size_t len) {
  StringBuf b;
  sbinit(&b, buf, buflen);
  char xbuf[len * 2 + 5];
  size_t esclen;

  esclen = dbescapestring(xbuf, (char *)data, len);
  sbaddchar(&b, '\'');
  sbaddstrlen(&b, xbuf, esclen);
  sbaddchar(&b, '\'');

  if(!sbterminate(&b))
    return 0;

  return 1;
}
Пример #7
0
static const char *
relocate_path(const char *dir, const char *s)
{
  SB sb;
  const char *r;
  const char *execdir = LUA_EXECDIR;
  int lexecdir = strlen(execdir);
  int ldir = strlen(dir);
  sbinit(&sb);
  while ((r = strstr(s, execdir)))
    {
      sbaddn(&sb, s, r-s);
      sbaddn(&sb, dir, ldir);
      s = r + lexecdir;
      while (is_slash(s[0]))
        {
          if (is_dot(s[1]) && is_slash(s[2]))
            {
              s += 2;
              continue;
            }
          if (is_dot(s[1]) && is_dot(s[2]) && is_slash(s[3]) )
            {
              s += 3;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && !is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              while (sb.buffer && sb.len>0 && is_slash(sb.buffer[sb.len-1]))
                sb.len -= 1;
              continue;
            }
          break;
        }
    }
  sbaddn(&sb, s, strlen(s));
  sbadd1(&sb, 0);
#ifdef LUA_WIN
  r = _strdup(sb.buffer);
#else
  r = strdup(sb.buffer);
#endif
  sbfree(&sb);
  return r;
}
Пример #8
0
/*
 | so_recv gets called when there is at least
 | an iSCSI header in the queue
 */
static int
so_recv(isc_session_t *sp, pduq_t *pq)
{
     struct socket	*so = sp->soc;
     sn_t		*sn = &sp->sn;
     struct uio		*uio = &pq->uio;
     struct sockbuf	sbp;
     pdu_t		*pp;
     int		error;
     size_t		n, len;
     bhs_t		*bhs;
     u_int		max, exp;

     debug_called(8);
     /*
      | now calculate how much data should be in the buffer
      | NOTE: digest is not verified/calculated - yet
      */
     pp = &pq->pdu;
     bhs = &pp->ipdu.bhs;

     sbinit(&sbp, 0);
     len = 0;
     if(bhs->AHSLength) {
	  pp->ahs_len = bhs->AHSLength * 4;
	  len += pp->ahs_len;
     }
     if(sp->hdrDigest)
	  len += 4;
     if(bhs->DSLength) {
	  n = bhs->DSLength;
#if BYTE_ORDER == LITTLE_ENDIAN
	  pp->ds_len = ((n & 0x00ff0000) >> 16)
	       | (n & 0x0000ff00)
	       | ((n & 0x000000ff) << 16);
#else
	  pp->ds_len = n;
#endif
	  len += pp->ds_len;
	  while(len & 03)
	       len++;
	  if(sp->dataDigest)
	       len += 4;
     }
Пример #9
0
static void
ncp_watchdog(struct ncp_conn *conn) {
	char *buf;
	int error, len, flags;
	struct socket *so;
	struct sockaddr *sa;
	struct sockbuf sio;

	sa = NULL;
	while (conn->wdg_so) { /* not a loop */
		so = conn->wdg_so;
		sbinit(&sio, 1000000);
		flags = MSG_DONTWAIT;
		error = so_pru_soreceive(so, (struct sockaddr**)&sa,
					 NULL, &sio, NULL, &flags);
		if (error)
			break;
		len = sio.sb_cc;
		NCPSDEBUG("got watch dog %d\n",len);
		if (len != 2) {
			m_freem(sio.sb_mb);
			break;
		}
		buf = mtod(sio.sb_mb, char *);
		if (buf[1] != '?') {
			m_freem(sio.sb_mb);
			break;
		}
		buf[1] = 'Y';
		error = so_pru_sosend(so, sa, NULL, sio.sb_mb, NULL, 0, curthread);
		NCPSDEBUG("send watch dog %d\n",error);
		break;
	}
	if (sa)
		kfree(sa, M_SONAME);
	return;
}
Пример #10
0
/*
 * portal_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
 *	       struct file *a_fp)
 */
static int
portal_open(struct vop_open_args *ap)
{
	struct socket *so = 0;
	struct portalnode *pt;
	struct thread *td = curthread;
	struct vnode *vp = ap->a_vp;
	struct uio auio;
	struct iovec aiov[2];
	struct sockbuf sio;
	int res;
	struct mbuf *cm = 0;
	struct cmsghdr *cmsg;
	int newfds;
	int *ip;
	int fd;
	int error;
	int len;
	struct portalmount *fmp;
	struct file *fp;
	struct portal_cred pcred;

	/*
	 * Nothing to do when opening the root node.
	 */
	if (vp->v_flag & VROOT)
		return (vop_stdopen(ap));

	/*
	 * Can't be opened unless the caller is set up
	 * to deal with the side effects.  Check for this
	 * by testing whether the p_dupfd has been set.
	 */
	KKASSERT(td->td_proc);
	if (td->td_lwp->lwp_dupfd >= 0)
		return (ENODEV);

	pt = VTOPORTAL(vp);
	fmp = VFSTOPORTAL(vp->v_mount);

	/*
	 * Create a new socket.
	 */
	error = socreate(AF_UNIX, &so, SOCK_STREAM, 0, td);
	if (error)
		goto bad;

	/*
	 * Reserve some buffer space
	 */
	res = pt->pt_size + sizeof(pcred) + 512;	/* XXX */
	error = soreserve(so, res, res, &td->td_proc->p_rlimit[RLIMIT_SBSIZE]);
	if (error)
		goto bad;

	/*
	 * Kick off connection
	 */
	error = portal_connect(so, (struct socket *)fmp->pm_server->f_data);
	if (error)
		goto bad;

	/*
	 * Wait for connection to complete
	 */
	/*
	 * XXX: Since the mount point is holding a reference on the
	 * underlying server socket, it is not easy to find out whether
	 * the server process is still running.  To handle this problem
	 * we loop waiting for the new socket to be connected (something
	 * which will only happen if the server is still running) or for
	 * the reference count on the server socket to drop to 1, which
	 * will happen if the server dies.  Sleep for 5 second intervals
	 * and keep polling the reference count.   XXX.
	 */
	crit_enter();
	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
		if (fmp->pm_server->f_count == 1) {
			error = ECONNREFUSED;
			crit_exit();
			goto bad;
		}
		(void) tsleep((caddr_t) &so->so_timeo, 0, "portalcon", 5 * hz);
	}
	crit_exit();

	if (so->so_error) {
		error = so->so_error;
		goto bad;
	}

	/*
	 * Set miscellaneous flags
	 */
	so->so_rcv.ssb_timeo = 0;
	so->so_snd.ssb_timeo = 0;
	atomic_set_int(&so->so_rcv.ssb_flags, SSB_NOINTR);
	atomic_set_int(&so->so_snd.ssb_flags, SSB_NOINTR);


	pcred.pcr_flag = ap->a_mode;
	pcred.pcr_uid = ap->a_cred->cr_uid;
	pcred.pcr_ngroups = ap->a_cred->cr_ngroups;
	bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t));
	aiov[0].iov_base = (caddr_t) &pcred;
	aiov[0].iov_len = sizeof(pcred);
	aiov[1].iov_base = pt->pt_arg;
	aiov[1].iov_len = pt->pt_size;
	auio.uio_iov = aiov;
	auio.uio_iovcnt = 2;
	auio.uio_rw = UIO_WRITE;
	auio.uio_segflg = UIO_SYSSPACE;
	auio.uio_td = td;
	auio.uio_offset = 0;
	auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len;

	error = sosend(so, NULL, &auio, NULL, NULL, 0, td);
	if (error)
		goto bad;

	len = sizeof(int);
	sbinit(&sio, len);
	do {
		struct mbuf *m;
		int flags;

		flags = MSG_WAITALL;
		error = soreceive(so, NULL, NULL, &sio, &cm, &flags);
		if (error)
			goto bad;

		/*
		 * Grab an error code from the mbuf.
		 */
		if ((m = sio.sb_mb) != NULL) {
			m = m_pullup(m, sizeof(int));	/* Needed? */
			if (m) {
				error = *(mtod(m, int *));
				m_freem(m);
			} else {
				error = EINVAL;
			}
		} else {
Пример #11
0
static int
lua_dir(lua_State *L)
{
  int k = 0;
  const char *s = luaL_checkstring(L, 1);

#ifdef _WIN32

  SB sb;
  struct _finddata_t info;
  long hfind;
  /* special cases */
  lua_createtable(L, 0, 0);
  if ((s[0]=='/' || s[0]=='\\') && 
      (s[1]=='/' || s[1]=='\\') && !s[2]) 
    {
      int drive;
      hfind = GetLogicalDrives();
      for (drive='A'; drive<='Z'; drive++)
        if (hfind & (1<<(drive-'A'))) {
          lua_pushfstring(L, "%c:/", drive);
          lua_rawseti(L, -2, ++k);
        }
    } 
  else if (dirp(L, 1)) {
    lua_pushliteral(L, "..");
    lua_rawseti(L, -2, ++k);
  } else {
    lua_pushnil(L);
    return 1;
  }
  /* files */
  sbinit(&sb);
  sbaddn(&sb, s, strlen(s));
  if (sb.len>0 && sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\')
    sbadd1(&sb, '/');
  sbaddn(&sb, "*.*", 3);
  sbadd1(&sb, 0);
  hfind = _findfirst(sb.buffer, &info);
  if (hfind != -1) {
    do {
      if (strcmp(".",info.name) && strcmp("..",info.name)) {
        lua_pushstring(L, info.name);
        lua_rawseti(L, -2, ++k);
      }
    } while ( _findnext(hfind, &info) != -1 );
    _findclose(hfind);
  }
  sbfree(&sb);

#else

  DIR *dirp;
  struct dirent *d;
  dirp = opendir(s);
  if (dirp) {
    lua_createtable(L, 0, 0);
    while ((d = readdir(dirp))) {
      int n = NAMLEN(d);
      lua_pushlstring(L, d->d_name, n);
      lua_rawseti(L, -2, ++k);
    }
    closedir(dirp);
  } else
    lua_pushnil(L);

#endif
  
  return 1;
}
Пример #12
0
static int 
concat_fname(lua_State *L, const char *fname)
{
  const char *from = lua_tostring(L, -1);

#ifdef _WIN32

  const char *s;
  SB sb;
  sbinit(&sb);
  sbaddn(&sb, from, strlen(from));
  if (fname==0)
    return sbpush(L, &sb);
  /* Handle absolute part of fname */
  if (fname[0]=='/' || fname[0]=='\\') {
    if (fname[1]=='/' || fname[1]=='\\') {
      sb.len = 0;                            /* Case //abcd */
      sbaddn(&sb, "//", 2);
    } else {
      char drive;
      if (sb.len >= 2 && sb.buffer[1]==':'   /* Case "/abcd" */
          && isalpha((unsigned char)(sb.buffer[0])) )
        drive = sb.buffer[0];
      else
        drive = _getdrive() + 'A' - 1;
      sb.len = 0;
      sbadd1(&sb, drive);
      sbaddn(&sb, ":/", 2);
    }
  } else if (fname[0] && 	              /* Case "x:abcd"   */
             isalpha((unsigned char)(fname[0])) && fname[1]==':') {
    if (fname[2]!='/' && fname[2]!='\\') {
      if (sb.len < 2 || sb.buffer[1]!=':' 
          || !isalpha((unsigned char)(sb.buffer[0]))
          || (toupper((unsigned char)sb.buffer[0]) !=
              toupper((unsigned char)fname[0]) ) ) 
        {
          int l;
          char drv[4];
          sb.len = 0;
          drv[0]=fname[0]; drv[1]=':'; drv[2]='.'; drv[3]=0;
          l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          if (l > sb.maxlen) {
            sbgrow(&sb, l+1);
            l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0);
          }
          if (l <= 0)
            sbaddn(&sb, drv, 3);
          else
            sb.len += l;
        }
      fname += 2;
    } else {
      sb.len = 0;                              /* Case "x:/abcd"  */
      sbadd1(&sb, toupper((unsigned char)fname[0])); 
      sbaddn(&sb, ":/", 2);
      fname += 2;
      while (*fname == '/' || *fname == '\\')
        fname += 1;
    }
  }
  /* Process path components */
  for (;;)
  {
    while (*fname=='/' || *fname=='\\')
      fname ++;
    if (*fname == 0)
      return sbpush(L, &sb);
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]=='\\' || fname[1]==0) {
	fname += 1;
	continue;
      }
      if (fname[1]=='.')
        if (fname[2]=='/' || fname[2]=='\\' || fname[2]==0) {
          size_t l;
	  fname += 2;
          lua_pushcfunction(L, lua_dirname);
          sbpush(L, &sb);
          lua_call(L, 1, 1);
          s = lua_tolstring(L, -1, &l);
          sbinit(&sb);
          sbaddn(&sb, s, l);
          lua_pop(L, 1);
	  continue;
      }
    }
    if (sb.len==0 || 
        (sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\') )
      sbadd1(&sb, '/');
    while (*fname && *fname!='/' && *fname!='\\')
      sbadd1(&sb, *fname++);
  }
             
#else
  SB sb;
  sbinit(&sb);

  if (fname && fname[0]=='/') 
    sbadd1(&sb, '/');
  else
    sbaddn(&sb, from, strlen(from));
  for (;;) {
    while (fname && fname[0]=='/')
      fname++;
    if (!fname || !fname[0]) {
      sbadd1(&sb, '/');
      while (sb.len > 1 && sb.buffer[sb.len-1]=='/')
        sb.len --;
      return sbpush(L, &sb);
    }
    if (fname[0]=='.') {
      if (fname[1]=='/' || fname[1]==0) {
	fname +=1;
	continue;
      }
      if (fname[1]=='.')
	if (fname[2]=='/' || fname[2]==0) {
	  fname +=2;
          while (sb.len > 0 && sb.buffer[sb.len-1]=='/')
            sb.len --;
          while (sb.len > 0 && sb.buffer[sb.len-1]!='/')
            sb.len --;
	  continue;
	}
    }
    if (sb.len == 0 || sb.buffer[sb.len-1] != '/')
      sbadd1(&sb, '/');
    while (*fname!=0 && *fname!='/')
      sbadd1(&sb, *fname++);
  }
  
  
#endif

}
Пример #13
0
static int 
lua_dirname(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);

#ifdef _WIN32

  const char *s;
  const char *p;
  SB sb;
  sbinit(&sb);
  /* Handle leading drive specifier */
  if (isalpha((unsigned char)fname[0]) && fname[1]==':') {
    sbadd1(&sb, *fname++);
    sbadd1(&sb, *fname++);
  }
  /* Search last non terminal / or \ */
  p = 0;
  s = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\') )
      p = s;
    s++;
  }
  /* Cannot find non terminal / or \ */
  if (p == 0) {
    if (sb.len > 0) {
      if (fname[0]==0 || fname[0]=='/' || fname[0]=='\\')
	sbadd1(&sb, '/');
      return sbpush(L, &sb);
    } else {
      if (fname[0]=='/' || fname[0]=='\\')
	return sbsetpush(L, &sb, "//");
      else
	return sbsetpush(L, &sb, ".");
    }
  }
  /* Single leading slash */
  if (p == fname) {
    sbadd1(&sb, '/');
    return sbpush(L, &sb);
  }
  /* Backtrack all slashes */
  while (p>fname && (p[-1]=='/' || p[-1]=='\\'))
    p--;
  /* Multiple leading slashes */
  if (p == fname)
    return sbsetpush(L, &sb, "//");
  /* Regular case */
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#else

  const char *s = fname;
  const char *p = 0;
  SB sb; 
  sbinit(&sb);
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s;
    s++;
  }
  if (!p) {
    if (fname[0]=='/')
      return sbsetpush(L, &sb, fname);
    else
      return sbsetpush(L, &sb, ".");
  }
  s = fname;
  do {
    sbadd1(&sb, *s++);
  } while (s<p);
  return sbpush(L, &sb);

#endif
}
Пример #14
0
static int 
lua_basename(lua_State *L)
{
  const char *fname = luaL_checkstring(L, 1);
  const char *suffix = luaL_optstring(L, 2, 0);

#ifdef _WIN32

  int sl;
  const char *p, *s;
  SB sb;
  sbinit(&sb);
  /* Special cases */
  if (fname[0] && fname[1]==':') {
    sbaddn(&sb, fname, 2);
    fname += 2;
    if (fname[0]=='/' || fname[0]=='\\')
      sbadd1(&sb, '/');
    while (fname[0]=='/' || fname[0]=='\\')
      fname += 1;
    if (fname[0]==0)
      return sbpush(L, &sb);
    sb.len = 0;
  }
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if ((s[0]=='\\' || s[0]=='/') &&
        (s[1] && s[1]!='/' && s[1]!='\\' ) )
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/' && *p!='\\')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && _strnicmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);
  
#else

  int sl;
  const char *s, *p;
  SB sb;
  sbinit(&sb);
  /* Position p after last nontrivial slash */
  s = p = fname;
  while (*s) {
    if (s[0]=='/' && s[1] && s[1]!='/')
      p = s + 1;
    s++;
  }
  /* Copy into buffer */
  while (*p && *p!='/')
    sbadd1(&sb, *p++);
  /* Process suffix */
  if (suffix==0 || suffix[0]==0)
    return sbpush(L, &sb);
  if (suffix[0]=='.')
    suffix += 1;
  if (suffix[0]==0)
    return sbpush(L, &sb);
  sl = strlen(suffix);
  if (sb.len > sl) {
    s =  sb.buffer + sb.len - (sl + 1);
    if (s[0]=='.' && strncmp(s+1,suffix, sl)==0)
      sb.len = s - sb.buffer;
  }
  return sbpush(L, &sb);

#endif
}
Пример #15
0
/*
 * When incoming data is appended to the socket, we get notified here.
 * This is also called whenever a significant event occurs for the socket.
 * Our original caller may have queued this even some time ago and 
 * we cannot trust that he even still exists. The node however is being
 * held with a reference by the queueing code and guarantied to be valid.
 */
static void
ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int arg2)
{
	struct socket *so = arg1;
	const priv_p priv = NG_NODE_PRIVATE(node);
	struct ng_mesg *response;
	int flags, error;

	crit_enter();

	/* so = priv->so; *//* XXX could have derived this like so */
	KASSERT(so == priv->so, ("%s: wrong socket", __func__));
	
	/* Allow next incoming event to be queued. */
	atomic_store_rel_int(&priv->fn_sent, 0);

	/* Check whether a pending connect operation has completed */
	if (priv->flags & KSF_CONNECTING) {
		if ((error = so->so_error) != 0) {
			so->so_error = 0;
			soclrstate(so, SS_ISCONNECTING);
		}
		if (!(so->so_state & SS_ISCONNECTING)) {
			NG_MKMESSAGE(response, NGM_KSOCKET_COOKIE,
			    NGM_KSOCKET_CONNECT, sizeof(int32_t), M_WAITOK | M_NULLOK);
			if (response != NULL) {
				response->header.flags |= NGF_RESP;
				response->header.token = priv->response_token;
				*(int32_t *)response->data = error;
				/* 
				 * send an async "response" message
				 * to the node that set us up
				 * (if it still exists)
				 */
				NG_SEND_MSG_ID(error, node,
				    response, priv->response_addr, 0);
			}
			priv->flags &= ~KSF_CONNECTING;
		}
	}

	/* Check whether a pending accept operation has completed */
	if (priv->flags & KSF_ACCEPTING) {
		error = ng_ksocket_check_accept(priv);
		if (error != EWOULDBLOCK)
			priv->flags &= ~KSF_ACCEPTING;
		if (error == 0)
			ng_ksocket_finish_accept(priv);
	}

	/*
	 * If we don't have a hook, we must handle data events later.  When
	 * the hook gets created and is connected, this upcall function
	 * will be called again.
	 */
	if (priv->hook == NULL) {
		crit_exit();
		return;
	}

	/* Read and forward available mbuf's */
	while (1) {
		struct sockaddr *sa = NULL;
		struct sockbuf sio;
		struct mbuf *n;

		sbinit(&sio, 1000000000);
		flags = MSG_DONTWAIT;

		/* Try to get next packet from socket */
		error = soreceive(so,
				((so->so_state & SS_ISCONNECTED) ? NULL : &sa),
				NULL, &sio, NULL, &flags);
		if (error)
			break;

		/* See if we got anything */
		if (sio.sb_mb == NULL) {
			if (sa != NULL)
				kfree(sa, M_SONAME);
			break;
		}

		/*
		 * Don't trust the various socket layers to get the
		 * packet header and length correct (e.g. kern/15175).
		 *
		 * Also, do not trust that soreceive() will clear m_nextpkt
		 * for us (e.g. kern/84952, kern/82413).
		 */
		sio.sb_mb->m_pkthdr.csum_flags = 0;
		sio.sb_mb->m_pkthdr.len = 0;
		for (n = sio.sb_mb; n != NULL; n = n->m_next) {
			sio.sb_mb->m_pkthdr.len += n->m_len;
			n->m_nextpkt = NULL;
		}

		/* Put peer's socket address (if any) into a tag */
		if (sa != NULL) {
			struct sa_tag	*stag;

			stag = (struct sa_tag *)m_tag_alloc(NGM_KSOCKET_COOKIE,
			    NG_KSOCKET_TAG_SOCKADDR, sizeof(ng_ID_t) +
			    sa->sa_len, MB_DONTWAIT);
			if (stag == NULL) {
				kfree(sa, M_SONAME);
				goto sendit;
			}
			bcopy(sa, &stag->sa, sa->sa_len);
			kfree(sa, M_SONAME);
			stag->id = NG_NODE_ID(node);
			m_tag_prepend(sio.sb_mb, &stag->tag);
		}

sendit:		/* Forward data with optional peer sockaddr as packet tag */
		NG_SEND_DATA_ONLY(error, priv->hook, sio.sb_mb);
	}

	/*
	 * If the peer has closed the connection, forward a 0-length mbuf
	 * to indicate end-of-file.
	 */
	if (so->so_state & SS_CANTRCVMORE && !(priv->flags & KSF_EOFSEEN)) {
		struct mbuf *m;

		MGETHDR(m, MB_DONTWAIT, MT_DATA);
		if (m != NULL) {
			m->m_len = m->m_pkthdr.len = 0;
			NG_SEND_DATA_ONLY(error, priv->hook, m);
		}
		priv->flags |= KSF_EOFSEEN;
	}
	crit_exit();
}