Exemplo n.º 1
0
static int
initiate(register Cs_t* state, char* user, char* path, char* service, char* name)
{
	register char*	s;
	char*		on;
	char*		local;
	Sfio_t*		sp;
	Sfio_t*		np;
	int		n;
	char*		av[REMOTE_ARGC];
	char		buf[PATH_MAX / 4];

	local = csname(state, 0);
	s = service + strlen(service);
	*s++ = '/';
	if (!(state->flags & CS_ADDR_SHARE))
	{
		sfsprintf(buf, sizeof(buf), "%s\n", state->host);
		if (!(sp = tokline(buf, SF_STRING, NiL)))
			return -1;
	}
	else if (state->flags & CS_ADDR_LOCAL)
	{
		sfsprintf(buf, sizeof(buf), "%s\n", CS_HOST_LOCAL);
		if (!(sp = tokline(buf, SF_STRING, NiL)))
			return -1;
	}
	else
	{
		strcpy(s, CS_SVC_HOSTS);
		if (!(sp = tokline(service, SF_READ, NiL)))
		{
			if (streq(state->host, CS_HOST_SHARE))
				sfsprintf(buf, sizeof(buf), "%s\n%s\n", CS_HOST_SHARE, CS_HOST_LOCAL);
			else
				sfsprintf(buf, sizeof(buf), "%s\n%s\n%s\n", state->host, CS_HOST_SHARE, CS_HOST_LOCAL);
			if (!(sp = tokline(buf, SF_STRING, NiL)))
				return -1;
		}
	}
	sfsprintf(s, PATH_MAX - (s - service) - 1, "%s%s", name, CS_SVC_SUFFIX);
	while (s = sfgetr(sp, '\n', 1))
		if (tokscan(s, NiL, " %s ", &on) == 1)
		{
			if (streq(on, CS_HOST_LOCAL) || streq(on, local))
			{
				sfclose(sp);
				av[0] = service;
				av[1] = path;
				av[2] = 0;
				return procclose(procopen(av[0], av, NiL, NiL, PROC_PRIVELEGED|PROC_ZOMBIE)) < 0 ? -1 : 0;
			}
			else if (!streq(on, CS_HOST_SHARE))
			{
				Proc_t*		proc;
				time_t		otime;
				struct stat	st;
				char		fv[REMOTE_FLAGC];
				long		ov[3];

				remote(state, on, user, path, 0, av, fv);
				otime = lstat(state->mount, &st) ? 0 : st.st_ctime;
				n = open("/dev/null", O_RDWR);
				ov[0] = PROC_FD_DUP(n, 0, 0);
				ov[1] = PROC_FD_DUP(n, 1, PROC_FD_PARENT|PROC_FD_CHILD);
				ov[2] = 0;
				if (proc = procopen(av[0], av, NiL, ov, PROC_PRIVELEGED|PROC_ZOMBIE))
				{
					n = 1;
					for (;;)
					{
						if (!lstat(state->mount, &st) && st.st_ctime != otime)
						{
							if (!procclose(proc))
							{
								sfclose(sp);
								return 0;
							}
							break;
						}

						/*
						 * sleep() and MNT_TMP
						 * hack around remote
						 * fs cache delays
						 */

						if (n >= CS_REMOTE_DELAY)
						{
							procclose(proc);
							break;
						}
						if (n == 1)
						{
							*state->control = CS_MNT_TMP;
							if (remove(state->mount))
							{
								close(open(state->mount, O_WRONLY|O_CREAT|O_TRUNC, 0));
								remove(state->mount);
							}
							*state->control = CS_MNT_STREAM;
						}
						sleep(n);
						n <<= 1;
					}
				}
			}
			else if (!sfstacked(sp) && (np = csinfo(state, on, NiL)))
				sfstack(sp, np);
		}
	sfclose(sp);
	return -1;
}
Exemplo n.º 2
0
unsigned long
csaddr(register Cs_t* state, const char* aname)
{
	register char*		name = (char*)aname;
	register char*		s;
	register unsigned long	addr;
	register Sfio_t*	sp = 0;
	int			userlen = 0;
	int			dot = 0;
	long			flags = 0;
	char*			user;

	messagef((state->id, NiL, -8, "addr(%s) call", name));
	if (!local)
	{
#if CS_LIB_SOCKET
		if (!state->db)
			state->db = -1;
#endif
		local = CS_LOCAL;
		if (addr = realaddr(state, csname(state, 0)))
			local = addr;
	}
	if (!name)
	{
		addr = local;
		goto ok;
	}
	if (s = strchr(name, '@'))
	{
		userlen = s - name;
		user = name;
		name = s + 1;
	}
	if (strneq(name, CS_HOST_SHARE, sizeof(CS_HOST_SHARE) - 1))
		switch (name[sizeof(CS_HOST_SHARE) - 1])
		{
		case 0:
			flags |= CS_ADDR_SHARE;
			if (sp = csinfo(state, name, NiL))
			{
				while (name = sfgetr(sp, '\n', 1))
					if (addr = realaddr(state, name))
						goto ok;
				sfclose(sp);
				sp = 0;
			}
			if (!(addr = realaddr(state, name = CS_HOST_GATEWAY)))
				addr = local;
			goto ok;
		case '.':
			flags |= CS_ADDR_SHARE;
			name += sizeof(CS_HOST_SHARE);
			break;
		}
	if (addr = realaddr(state, name))
		goto ok;
	if ((flags & CS_ADDR_SHARE) && !(state->flags & CS_ADDR_NUMERIC) && (s = strchr(name, '.')))
	{
		char*			sb;
		char*			se;
		char*			sx;
		char*			t;
		char*			te;

		dot = s - name;
		s = state->temp;
		sx = &state->temp[sizeof(state->temp) - 1];
		s += sfsprintf(s, sx - s, "%s/", CS_SVC_REMOTE);
		sb = s;
		se = 0;
		t = name;
		while (*t && s < sx)
		{
			if (s - sb >= CS_MNT_MAX)
			{
				if (se)
				{
					s = se - 1;
					t = te;
				}
				else
				{
					if (s >= sx) break;
					if (*t == '.') t++;
				}
				*s++ = '/';
				sb = s;
				se = 0;
			}
			if ((*s++ = *t++) == '.')
			{
				se = s;
				te = t;
			}
		}
		*s = 0;
		if (sp = csinfo(state, state->temp, NiL))
		{
			while (t = sfgetr(sp, '\n', 1))
			{
				if (s = strchr(t, '@')) s++;
				else s = t;
				if (addr = realaddr(state, s))
				{
					name = s;
					if (!userlen && s != t)
					{
						userlen = s - t - 1;
						user = t;
					}
					goto ok;
				}
			}
			sfclose(sp);
			sp = 0;
		}
		sfsprintf(state->temp, sizeof(state->temp), "%s.%s", CS_HOST_GATEWAY, name);
		if (addr = realaddr(state, state->temp))
		{
			name = state->temp;
			goto ok;
		}
		sfsprintf(state->temp, sizeof(state->temp), "%-.*s.%s", dot, name, name);
		if (addr = realaddr(state, state->temp))
		{
			name = state->temp;
			goto ok;
		}
	}
	messagef((state->id, NiL, -1, "addr: %s: not found", aname));
	return 0;
 ok:
	if (state->flags & CS_ADDR_NUMERIC)
		flags &= ~CS_ADDR_SHARE;
	if (addr == local)
	{
		flags |= CS_ADDR_LOCAL;
		name = csname(state, 0);
	}
	else if (!(state->flags & CS_ADDR_NUMERIC))
	{
		if (s = strchr(name, '.'))
		{
			sfsprintf(state->temp, sizeof(state->temp), "%-.*s", s - name, name);
			if (realaddr(state, state->temp) == addr)
				name = state->temp;
			else flags |= CS_ADDR_REMOTE;
		}
		if (!(flags & CS_ADDR_REMOTE) && !streq(name, CS_HOST_PROXY) && !csattr(state, name, "*"))
			flags |= CS_ADDR_REMOTE;
	}

	/*
	 * cache host name and user for possible CS_REMOTE_SHELL
	 */

	strncpy(state->host, name, sizeof(state->host) - 1);
	if (userlen)
	{
		if (userlen >= sizeof(state->user)) userlen = sizeof(state->user) - 1;
		strncpy(state->user, user, userlen);
	}
	state->user[userlen] = 0;
	if (sp) sfclose(sp);
	state->flags &= ~(CS_ADDR_LOCAL|CS_ADDR_NOW|CS_ADDR_REMOTE|CS_ADDR_SHARE|CS_DAEMON_SLAVE|CS_ADDR_TEST|CS_ADDR_TRUST);
	state->flags |= flags;
	messagef((state->id, NiL, -8, "addr(%s) = %s, flags = |%s%s%s", aname, csntoa(state, addr), (state->flags & CS_ADDR_LOCAL) ? "LOCAL|" : "", (state->flags & CS_ADDR_REMOTE) ? "REMOTE|" : "", (state->flags & CS_ADDR_SHARE) ? "SHARE|" : ""));
	return addr;
}