Пример #1
0
/*
 * Get a list of the Distfile Option Entries for each enabled
 * value in "opts".
 */
char *
getondistoptlist(opt_t opts)
{
    int i;
    static char buf[1024];

    for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) {
        if (!IS_ON(opts, distoptinfo[i].do_value))
            continue;

        if (buf[0] == CNULL)
            (void) strlcpy(buf, distoptinfo[i].do_name, sizeof buf);
        else {
            (void) strlcat(buf, ",", sizeof buf);
            (void) strlcat(buf, distoptinfo[i].do_name, sizeof buf);
        }
        if (distoptinfo[i].do_arg) {
            (void) strlcat(buf, "=", sizeof buf);
            (void) strlcat(buf, distoptinfo[i].do_arg, sizeof buf);
        }
    }

    return(buf);
}
Пример #2
0
int main(void)
{
    byte lamps = 0b00000000;
    byte opcao;

    do
    {
        printf("\n=======================\n");
        printf("       LÂMPADAS!       \n");
        printf("=======================\n\n");

        printf("1 - Estado das lâmpadas\n");
        printf("2 - Ligar lâmpada\n");
        printf("3 - Apagar lâmpada\n");
        printf("4 - Sair do programa\n\n");

        printf("Opção: ");

        scanf("%hu", (short*) &opcao);

        switch (opcao)
        {
        case 1:
        {
            byte idx;

            for (idx = 0; idx < 8; idx++)
            {
                printf("Lâmpada #%d: %s\n", idx+1,
                       (IS_ON(lamps, idx+1)) ? "ON" : "OFF");
            }
        }
        break;
        case 2:
        {
            byte position;

            printf("Posição: ");
            scanf("%hu", (short*) &position);

            TURN_ON(lamps, position);
        }
        break;
        case 3:
        {
            byte position;

            printf("Posição: ");
            scanf("%hu", (short*) &position);

            TURN_OFF(lamps, position);
        }
        break;
        case 4:
            break;
        default :
            printf("\n\nOpção incorreta!");
        }
    } while (opcao != 4);

    return 0;
}
Пример #3
0
/*
 * Do the commands in cmds (initialized by yyparse).
 */
void
docmds(struct namelist *hostlist, int argc, char **argv)
{
	struct cmd *c;
	char *cp;
	int i;

	(void) signal(SIGHUP, sighandler);
	(void) signal(SIGINT, sighandler);
	(void) signal(SIGQUIT, sighandler);
	(void) signal(SIGTERM, sighandler);

	if (!nflag)
		mysetlinebuf(stdout);	/* Make output (mostly) clean */

#if	defined(USE_STATDB)
	if (!nflag && (dostatdb || juststatdb)) {
		extern long reccount;
		message(MT_INFO, "Making stat database [%s] ... \n", 
			       gettimestr());
		if (mkstatdb() < 0)
			error("Warning: Make stat database failed.");
		message(MT_INFO,
			      "Stat database created: %d files stored [%s].\n",
			       reccount, gettimestr());
		if (juststatdb)
			return;
	}
#endif	/* USE_STATDB */

	/*
	 * Print errors for any command line targets we didn't find.
	 * If any errors are found, return to main() which will then exit.
	 */
	for (i = 0; i < argc; i++) {
		int found;

		for (found = FALSE, c = cmds; c != NULL; c = c->c_next) {
			if (c->c_label && argv[i] && 
			    strcmp(c->c_label, argv[i]) == 0) {
				found = TRUE;
				break;
			}
		}
		if (!found)
			error("Label \"%s\" is not defined in the distfile.", 
			      argv[i]);
	}
	if (nerrs)
		return;

	/*
	 * Main command loop.  Loop through all the commands.
	 */
	for (c = cmds; c != NULL; c = c->c_next) {
		checkcmd(c);
		if (do_fork) {
			/*
			 * Let the children take care of their assigned host
			 */
			if (amchild) {
				if (strcmp(c->c_name, currenthost) != 0)
					continue;
			} else if (c->c_flags & CMD_ASSIGNED) {
				/* This cmd has been previously assigned */
				debugmsg(DM_MISC, "prev assigned: %s\n",
					 c->c_name);
				continue;
			}
		}

		if (hostlist) {
			/* Do specific hosts as specified on command line */
			struct namelist *nlptr;

			for (nlptr = hostlist; nlptr; nlptr = nlptr->n_next)
				/*
				 * Try an exact match and then a match
				 * without '@' (if present).
				 */
				if ((strcmp(c->c_name, nlptr->n_name) == 0) ||
				    ((cp = strchr(c->c_name, '@')) &&
				     strcmp(++cp, nlptr->n_name) == 0))
					docmd(c, argc, argv);
			continue;
		} else
			/* Do all of the command */
			docmd(c, argc, argv);
	}

	if (do_fork) {
		/*
		 * We're multi-threaded, so do appropriate shutdown
		 * actions based on whether we're the parent or a child.
		 */
		if (amchild) {
			if (!IS_ON(options, DO_QUIET))
				message(MT_VERBOSE, "updating of %s finished", 
					currenthost);
			closeconn();
			cleanup(0);
			exit(nerrs);
		}

		/*
		 * Wait for all remaining active children to finish
		 */
		while (activechildren > 0) {
			debugmsg(DM_MISC, 
				 "Waiting for %d children to finish.\n",
				 activechildren);
			waitup();
		}
	} else if (!nflag) {
		/*
		 * We're single-threaded so close down current connection
		 */
		closeconn();
		cleanup(0);
	}
}
Пример #4
0
/*
 * Notify the list of people the changes that were made.
 * rhost == NULL if we are mailing a list of changes compared to at time
 * stamp file.
 */
static void
notify(char *rhost, struct namelist *to, time_t lmod)
{
	int fd;
	ssize_t len;
	FILE *pf;
	struct stat stb;
	static char buf[BUFSIZ];
	extern char *locuser;
	char *file, *user;

	if (IS_ON(options, DO_VERIFY) || to == NULL)
		return;

	if ((file = getnotifyfile()) == NULL)
		return;

	if (!IS_ON(options, DO_QUIET)) {
		message(MT_INFO, "notify %s%s %s", 
			(rhost) ? "@" : "",
			(rhost) ? rhost : "", getnlstr(to));
	}

	if (nflag)
		return;

	debugmsg(DM_MISC, "notify() temp file = '%s'", file);

	if ((fd = open(file, O_RDONLY)) < 0) {
		error("%s: open for reading failed: %s", file, SYSERR);
		return;
	}
	if (fstat(fd, &stb) < 0) {
		error("%s: fstat failed: %s", file, SYSERR);
		(void) close(fd);
		return;
	}
	if (stb.st_size == 0) {
		(void) close(fd);
		return;
	}
	/*
	 * Create a pipe to mailing program.
	 * Set IFS to avoid possible security problem with users
	 * setting "IFS=/".
	 */
	(void) snprintf(buf, sizeof(buf), "IFS=\" \t\"; export IFS; %s -oi -t", 
		       _PATH_SENDMAIL);
	pf = popen(buf, "w");
	if (pf == NULL) {
		error("notify: \"%s\" failed\n", _PATH_SENDMAIL);
		(void) unlink(file);
		(void) close(fd);
		return;
	}
	/*
	 * Output the proper header information.
	 */
	(void) fprintf(pf, "Auto-Submitted: auto-generated\n");
	(void) fprintf(pf, "From: rdist (Remote distribution program)\n");
	(void) fprintf(pf, "To:");
	if (!any('@', to->n_name) && rhost != NULL)
		(void) fprintf(pf, " %s@%s", to->n_name, rhost);
	else
		(void) fprintf(pf, " %s", to->n_name);
	to = to->n_next;
	while (to != NULL) {
		if (!any('@', to->n_name) && rhost != NULL)
			(void) fprintf(pf, ", %s@%s", to->n_name, rhost);
		else
			(void) fprintf(pf, ", %s", to->n_name);
		to = to->n_next;
	}
	(void) putc('\n', pf);

	if ((user = getlogin()) == NULL)
		user = locuser;

	if (rhost != NULL)
		(void) fprintf(pf, 
			 "Subject: files updated by %s from %s to %s\n",
			 locuser, host, rhost);
	else
		(void) fprintf(pf, "Subject: files updated after %s\n", 
			       ctime(&lmod));
	(void) putc('\n', pf);
	(void) putc('\n', pf);
	(void) fprintf(pf, "Options: %s\n\n", getondistoptlist(options));

	while ((len = read(fd, buf, sizeof(buf))) > 0)
		(void) fwrite(buf, 1, len, pf);

	(void) pclose(pf);
	(void) close(fd);
	(void) unlink(file);
}
Пример #5
0
/*
 * Process commands for comparing files to time stamp files.
 */
static void
dodcolon(struct cmd *cmd, char **filev)
{
	struct subcmd *sc;
	struct namelist *f;
	char *cp, **cpp;
	struct stat stb;
	struct namelist *files = cmd->c_files;
	struct subcmd *sbcmds = cmd->c_cmds;
	char *env, *stamp = cmd->c_name;

	debugmsg(DM_CALL, "dodcolon()");

	if (files == NULL) {
		error("No files to be updated for target \"%s\"", 
		      cmd->c_label);
		return;
	}
	if (stat(stamp, &stb) < 0) {
		error("%s: stat failed: %s", stamp, SYSERR);
		return;
	}

	debugmsg(DM_MISC, "%s: mtime %d\n", stamp, stb.st_mtime);

	env = NULL;
	for (sc = sbcmds; sc != NULL; sc = sc->sc_next) {
		if (sc->sc_type == CMDSPECIAL) {
			env = (char *) xmalloc(sizeof(E_FILES) + 3);
			(void) snprintf(env, sizeof(E_FILES) + 3,
					"%s='", E_FILES);
			break;
		}
	}

	subcmds = sbcmds;
	filelist = files;

	lastmod = stb.st_mtime;
	if (!nflag && !IS_ON(options, DO_VERIFY))
		/*
		 * Set atime and mtime to current time
		 */
		(void) setfiletime(stamp, (time_t) 0, (time_t) 0);

	for (f = files; f != NULL; f = f->n_next) {
		if (filev) {
			for (cpp = filev; *cpp; cpp++)
				if (strcmp(f->n_name, *cpp) == 0)
					goto found;
			continue;
		}
	found:
		ptarget = NULL;
		cmptime(f->n_name, sbcmds, &env);
	}

	for (sc = sbcmds; sc != NULL; sc = sc->sc_next) {
		if (sc->sc_type == NOTIFY)
			notify(NULL, sc->sc_args, (time_t)lastmod);
		else if (sc->sc_type == CMDSPECIAL && env) {
			size_t len = strlen(env);
			if (env[len - 1] == ':')
				env[--len] = CNULL;
			len += 2 + strlen(sc->sc_name) + 1;
			env = xrealloc(env, len);
			(void) strlcat(env, "';", len);
			(void) strlcat(env, sc->sc_name, len);
			message(MT_CHANGE, "cmdspecial \"%s\"", env);
			if (!nflag && IS_OFF(options, DO_VERIFY))
				runcommand(env);
			(void) free(env);
			env = NULL;	/* so cmdspecial is only called once */
		}
	}
	if (!nflag && !IS_ON(options, DO_VERIFY) && (cp = getnotifyfile()))
		(void) unlink(cp);
}
Пример #6
0
/*
 * Compare the mtime of file to the list of time stamps.
 */
static void
cmptime(char *name, struct subcmd *sbcmds, char **env)
{
	struct subcmd *sc;
	struct stat stb;

	debugmsg(DM_CALL, "cmptime(%s)", name);

	if (except(name))
		return;

	if (nflag) {
		(void) printf("comparing dates: %s\n", name);
		return;
	}

	/*
	 * first time cmptime() is called?
	 */
	if (ptarget == NULL) {
		if (exptilde(target, name, sizeof(target)) == NULL)
			return;
		ptarget = name = target;
		while (*ptarget)
			ptarget++;
	}
	if (access(name, R_OK) < 0 || stat(name, &stb) < 0) {
		error("%s: cannot access file: %s", name, SYSERR);
		return;
	}

	if (S_ISDIR(stb.st_mode)) {
		rcmptime(&stb, sbcmds, env);
		return;
	} else if (!S_ISREG(stb.st_mode)) {
		error("%s: not a plain file", name);
		return;
	}

	if (stb.st_mtime > lastmod) {
		message(MT_INFO, "%s: file is newer", name);
		for (sc = sbcmds; sc != NULL; sc = sc->sc_next) {
			char buf[BUFSIZ];
			if (sc->sc_type != SPECIAL)
				continue;
			if (sc->sc_args != NULL && !inlist(sc->sc_args, name))
				continue;
			(void) snprintf(buf, sizeof(buf), "%s=%s;%s", 
				        E_LOCFILE, name, sc->sc_name);
			message(MT_CHANGE, "special \"%s\"", buf);
			if (*env) {
				size_t len = strlen(*env) + strlen(name) + 2;
				*env = (char *) xrealloc(*env, len);
				(void) strlcat(*env, name, len);
				(void) strlcat(*env, ":", len);
			}
			if (IS_ON(options, DO_VERIFY))
				continue;

			runcommand(buf);
		}
	}
}
Пример #7
0
/*
 * Process commands for sending files to other machines.
 */
static void
doarrow(struct cmd *cmd, char **filev)
{
	struct namelist *f;
	struct subcmd *sc;
	char **cpp;
	int n, ddir, destdir;
	volatile opt_t opts = options;
	struct namelist *files;
	struct subcmd *sbcmds;
	char *rhost;
	volatile int didupdate = 0;

        if (setjmp_ok) {
		error("reentrant call to doarrow");
		abort();
	}

	if (!cmd) {
		debugmsg(DM_MISC, "doarrow() NULL cmd parameter");
		return;
	}

	files = cmd->c_files;
	sbcmds = cmd->c_cmds;
	rhost = cmd->c_name;

	if (files == NULL) {
		error("No files to be updated on %s for target \"%s\"", 
		      rhost, cmd->c_label);
		return;
	}

	debugmsg(DM_CALL, "doarrow(%x, %s, %x) start", 
		 files, A(rhost), sbcmds);

	if (nflag)
		(void) printf("updating host %s\n", rhost);
	else {
		if (cmd->c_flags & CMD_CONNFAILED) {
			debugmsg(DM_MISC,
				 "makeconn %s failed before; skipping\n",
				 rhost);
			return;
		}

		if (setjmp(finish_jmpbuf)) {
			setjmp_ok = FALSE;
			debugmsg(DM_MISC, "setjmp to finish_jmpbuf");
			markfailed(cmd, cmds);
			return;
		}
		setjmp_ok = TRUE;

		if (!makeconn(rhost)) {
			setjmp_ok = FALSE;
			markfailed(cmd, cmds);
			return;
		}
	}

	subcmds = sbcmds;
	filelist = files;

	n = 0;
	for (sc = sbcmds; sc != NULL; sc = sc->sc_next) {
		if (sc->sc_type != INSTALL)
			continue;
		n++;
	/*
	 * destination is a directory if one of the following is true:
	 * a) more than one name specified on left side of -> directive
	 * b) basename of destination in "install" directive is "."
	 *    (e.g. install /tmp/.;)
	 * c) name on left side of -> directive is a directory on local system.
 	 *
 	 * We need 2 destdir flags (destdir and ddir) because single directory
 	 * source is handled differently.  In this case, ddir is 0 (which
 	 * tells install() not to send DIRTARGET directive to remote rdistd)
 	 * and destdir is 1 (which tells remfilename() how to build the FILE
 	 * variables correctly).  In every other case, destdir and ddir will
 	 * have the same value.
	 */
  	ddir = files->n_next != NULL;	/* destination is a directory */
	if (!ddir) {
		struct stat s;
 		int isadir = 0;

		if (lstat(files->n_name, &s) == 0)
 			isadir = S_ISDIR(s.st_mode);
 		if (!isadir && sc->sc_name && *sc->sc_name)
 			ddir = !strcmp(xbasename(sc->sc_name),".");
 		destdir = isadir | ddir;
 	} else
 		destdir = ddir;

	debugmsg(DM_MISC,
		 "Debug files->n_next= %d, destdir=%d, ddir=%d",
		 files->n_next, destdir, ddir);
 
	if (!sc->sc_name || !*sc->sc_name) {
		destdir = 0;
		ddir = 0;
	}

	debugmsg(DM_MISC,
		 "Debug sc->sc_name=%x, destdir=%d, ddir=%d",
		 sc->sc_name, destdir, ddir);

	for (f = files; f != NULL; f = f->n_next) {
		if (filev) {
			for (cpp = filev; *cpp; cpp++)
				if (strcmp(f->n_name, *cpp) == 0)
					goto found;
			continue;
		}
	found:
		if (install(f->n_name, sc->sc_name, ddir, destdir,
				sc->sc_options) > 0)
			++didupdate;
		opts = sc->sc_options;
	}

	} /* end loop for each INSTALL command */

	/* if no INSTALL commands present, do default install */
	if (!n) {
		for (f = files; f != NULL; f = f->n_next) {
			if (filev) {
				for (cpp = filev; *cpp; cpp++)
					if (strcmp(f->n_name, *cpp) == 0)
						goto found2;
				continue;
			}
		found2:
			/* ddir & destdir set to zero for default install */
			if (install(f->n_name, NULL, 0, 0, options) > 0)
				++didupdate;
		}
	}

	/*
	 * Run any commands for the entire cmd
	 */
	if (didupdate > 0) {
		runcmdspecial(cmd, opts);
		didupdate = 0;
	}

	if (!nflag)
		(void) signal(SIGPIPE, cleanup);

	for (sc = sbcmds; sc != NULL; sc = sc->sc_next)
		if (sc->sc_type == NOTIFY)
			notify(rhost, sc->sc_args, (time_t) 0);

	if (!nflag) {
		struct linkbuf *nextl, *l;

		for (l = ihead; l != NULL; freelinkinfo(l), l = nextl) {
			nextl = l->nextp;
			if (contimedout || IS_ON(opts, DO_IGNLNKS) || 
			    l->count == 0)
				continue;
			message(MT_WARNING, "%s: Warning: %d %s link%s",
				l->pathname, abs(l->count),	
				(l->count > 0) ? "missing" : "extra",
				(l->count == 1) ? "" : "s");
		}
		ihead = NULL;
	}
	setjmp_ok = FALSE;
}
Пример #8
0
/*
 * Create a connection to the rdist server on the machine rhost.
 * Return 0 if the connection fails or 1 if it succeeds.
 */
static int
makeconn(char *rhost)
{
	char *ruser, *cp;
	static char *cur_host = NULL;
	extern char *locuser;
	extern int64_t min_freefiles, min_freespace;
	extern char *remotemsglist;
	char tuser[BUFSIZ], buf[BUFSIZ];
	u_char respbuff[BUFSIZ];
	int n;

	debugmsg(DM_CALL, "makeconn(%s)", rhost);

	/*
	 * See if we're already connected to this host
	 */
	if (cur_host != NULL && rem_w >= 0) {
		if (strcmp(cur_host, rhost) == 0)
			return(1);
		closeconn();
	}

	/*
	 * Determine remote user and current host names
	 */
	cur_host = rhost;
	cp = strchr(rhost, '@');

	if (cp != NULL) {
		char c = *cp;

		*cp = CNULL;
		(void) strlcpy((char *)tuser, rhost, sizeof(tuser));
		*cp = c;
		rhost = cp + 1;
		ruser = tuser;
		if (*ruser == CNULL)
			ruser = locuser;
		else if (!okname(ruser))
			return(0);
	} else
		ruser = locuser;

	if (!IS_ON(options, DO_QUIET))
		message(MT_VERBOSE, "updating host %s", rhost);

	(void) snprintf(buf, sizeof(buf), "%.*s -S",
			(int)(sizeof(buf)-5), path_rdistd);
		
	if ((rem_r = rem_w = remotecmd(rhost, locuser, ruser, buf)) < 0)
		return(0);

	/*
	 * First thing received should be S_VERSION
	 */
	respbuff[0] = '\0';
	n = remline(respbuff, sizeof(respbuff), TRUE);
	if (n <= 0 || respbuff[0] != S_VERSION) {
		if (n > 0)
		    error("Unexpected input from server: \"%s\".", respbuff);
		else
		    error("No input from server.");
		closeconn();
		return(0);
	}

	/*
	 * For future compatibility we check to see if the server
	 * sent it's version number to us.  If it did, we use it,
	 * otherwise, we send our version number to the server and let
	 * it decide if it can handle our protocol version.
	 */
	if (respbuff[1] == CNULL) {
		/*
		 * The server wants us to send it our version number
		 */
		(void) sendcmd(S_VERSION, "%d", VERSION);
		if (response() < 0) 
			return(0);
	} else {
		/*
		 * The server sent it's version number to us
		 */
		proto_version = atoi(&respbuff[1]);
		if (proto_version != VERSION) {
			fatalerr(
		  "Server version (%d) is not the same as local version (%d).",
			      proto_version, VERSION);
			return(0);
		}
	}

	/*
	 * Send config commands
	 */
	if (host[0]) {
		(void) sendcmd(C_SETCONFIG, "%c%s", SC_HOSTNAME, host);
		if (response() < 0)
			return(0);
	}
	if (min_freespace) {
		(void) sendcmd(C_SETCONFIG, "%c%lld", SC_FREESPACE, 
			       min_freespace);
		if (response() < 0)
			return(0);
	}
	if (min_freefiles) {
		(void) sendcmd(C_SETCONFIG, "%c%lld", SC_FREEFILES, 
			       min_freefiles);
		if (response() < 0)
			return(0);
	}
	if (remotemsglist) {
		(void) sendcmd(C_SETCONFIG, "%c%s", SC_LOGGING, remotemsglist);
		if (response() < 0)
			return(0);
	}
	if (strcmp(defowner, "bin") != 0) {
		(void) sendcmd(C_SETCONFIG, "%c%s", SC_DEFOWNER, defowner);
		if (response() < 0)
			return(0);
	}
	if (strcmp(defgroup, "bin") != 0) {
		(void) sendcmd(C_SETCONFIG, "%c%s", SC_DEFGROUP, defgroup);
		if (response() < 0)
			return(0);
	}

	return(1);
}