Пример #1
0
void sync_browse_lists(struct work_record *work,
		       char *name, int nm_type, 
		       struct in_addr ip, bool local, bool servers)
{
	struct sync_record *s;
	static int counter;

	START_PROFILE(sync_browse_lists);
	/* Check we're not trying to sync with ourselves. This can
	   happen if we are a domain *and* a local master browser. */
	if (ismyip_v4(ip)) {
done:
		END_PROFILE(sync_browse_lists);
		return;
	}

	s = SMB_MALLOC_P(struct sync_record);
	if (!s) goto done;

	ZERO_STRUCTP(s);

	unstrcpy(s->workgroup, work->work_group);
	unstrcpy(s->server, name);
	s->ip = ip;

	if (asprintf(&s->fname, "%s/sync.%d", lp_lockdir(), counter++) < 0) {
		SAFE_FREE(s);
		goto done;
	}
	/* Safe to use as 0 means no size change. */
	all_string_sub(s->fname,"//", "/", 0);

	DLIST_ADD(syncs, s);

	/* the parent forks and returns, leaving the child to do the
	   actual sync and call END_PROFILE*/
	CatchChild();
	if ((s->pid = sys_fork())) return;

	BlockSignals( False, SIGTERM );

	DEBUG(2,("Initiating browse sync for %s to %s(%s)\n",
		 work->work_group, name, inet_ntoa(ip)));

	fp = x_fopen(s->fname,O_WRONLY|O_CREAT|O_TRUNC, 0644);
	if (!fp) {
		END_PROFILE(sync_browse_lists);
		_exit(1);
	}

	sync_child(name, nm_type, work->work_group, ip, local, servers,
		   s->fname);

	x_fclose(fp);
	END_PROFILE(sync_browse_lists);
	_exit(0);
}
Пример #2
0
/*
 * prb_child_create()  - this routine instantiates and rendevous with the
 * target child process.  This routine returns an opaque handle for the
 * childs /proc entry.
 */
prb_status_t
prb_child_create(const char *cmdname, char * const *cmdargs,
                 const char *loption, const char *libtnfprobe_path,
                 char * const *envp, prb_proc_ctl_t **ret_val)
{
    prb_status_t	prbstat;
    pid_t		childpid;
    char		executable_name[PATH_MAX + 2];
    extern char 	**environ;
    char * const *	env_to_use;
    size_t		loptlen, probepathlen;
    volatile shmem_msg_t *smp;

    /* initialize shmem communication buffer to cause child to wait */
    prbstat = prb_shmem_init(&smp);
    if (prbstat)
        return (prbstat);

    /* fork to create the child process */
    childpid = fork();
    if (childpid == (pid_t) - 1) {
        DBG(perror("prb_child_create: fork failed"));
        return (prb_status_map(errno));
    }
    if (childpid == 0) {
        char		   *oldenv;
        char		   *newenv;

        /* ---- CHILD PROCESS ---- */

        DBG_TNF_PROBE_1(prb_child_create_1, "libtnfctl",
                        "sunw%verbosity 1; sunw%debug 'child process created'",
                        tnf_long, pid, getpid());

        if (envp) {
            env_to_use = envp;
            goto ContChild;
        }

        /* append libtnfprobe.so to the LD_PRELOAD environment */
        loptlen = (loption) ? strlen(loption) : 0;
        /* probepathlen has a "/" added in ("+ 1") */
        probepathlen = (libtnfprobe_path) ?
                       (strlen(libtnfprobe_path) + 1) : 0;
        oldenv = getenv(PRELOAD);
        if (oldenv) {
            newenv = (char *) malloc(strlen(PRELOAD) +
                                     1 +	/* "=" */
                                     strlen(oldenv) +
                                     1 +	/* " " */
                                     probepathlen +
                                     strlen(LIBPROBE) +
                                     1 +	/* " " */
                                     loptlen +
                                     1);	/* NULL */

            if (!newenv)
                goto ContChild;
            (void) strcpy(newenv, PRELOAD);
            (void) strcat(newenv, "=");
            (void) strcat(newenv, oldenv);
            (void) strcat(newenv, " ");
            if (probepathlen) {
                (void) strcat(newenv, libtnfprobe_path);
                (void) strcat(newenv, "/");
            }
            (void) strcat(newenv, LIBPROBE);
            if (loptlen) {
                (void) strcat(newenv, " ");
                (void) strcat(newenv, loption);
            }
        } else {
            newenv = (char *) malloc(strlen(PRELOAD) +
                                     1 +	/* "=" */
                                     probepathlen +
                                     strlen(LIBPROBE) +
                                     1 +	/* " " */
                                     loptlen +
                                     1);	/* NULL */
            if (!newenv)
                goto ContChild;
            (void) strcpy(newenv, PRELOAD);
            (void) strcat(newenv, "=");
            if (probepathlen) {
                (void) strcat(newenv, libtnfprobe_path);
                (void) strcat(newenv, "/");
            }
            (void) strcat(newenv, LIBPROBE);
            if (loptlen) {
                (void) strcat(newenv, " ");
                (void) strcat(newenv, loption);
            }
        }
        (void) putenv((char *) newenv);
        env_to_use = environ;
        /*
         * We don't check the return value of putenv because the
         * desired libraries might already be in the target, even
         * if our effort to change the environment fails.  We
         * should continue either way ...
         */
ContChild:
        /* wait until the parent releases us */
        (void) prb_shmem_wait(smp);

        DBG_TNF_PROBE_1(prb_child_create_2, "libtnfctl",
                        "sunw%verbosity 2; "
                        "sunw%debug 'child process about to exec'",
                        tnf_string, cmdname, cmdname);

        /*
         * make the child it's own process group.
         * This is so that signals delivered to parent are not
         * also delivered to child.
         */
        (void) setpgrp();
        prbstat = find_executable(cmdname, executable_name);
        if (prbstat) {
            DBG((void) fprintf(stderr, "prb_child_create: %s\n",
                               prb_status_str(prbstat)));
            /* parent waits for exit */
            _exit(1);
        }
        if (execve(executable_name, cmdargs, env_to_use) == -1) {
            DBG(perror("prb_child_create: exec failed"));
            _exit(1);
        }

        /* Never reached */
        _exit(1);
    }
    /* ---- PARENT PROCESS ---- */
    /* child is waiting for us */

    prbstat = sync_child(childpid, smp, ret_val);
    if (prbstat) {
        return (prbstat);
    }

    return (PRB_STATUS_OK);

}