示例#1
0
/*
 * Open input file with given define for C-preprocessor
 */
static void
open_input(const char *infile, const char *define)
{
	int pd[2];

	infilename = (infile == NULL) ? "<stdin>" : infile;
	(void) pipe(pd);
	switch (childpid = fork()) {
	case 0:
		prepend_cpp();
		addarg(define);
		if (infile)
			addarg(infile);
		addarg((char *)NULL);
		(void) close(1);
		(void) dup2(pd[1], 1);
		(void) close(pd[0]);
		execvp(arglist[0], arglist);
		err(1, "execvp %s", arglist[0]);
	case -1:
		err(1, "fork");
	}
	(void) close(pd[1]);
	fin = fdopen(pd[0], "r");
	if (fin == NULL) {
		warn("%s", infilename);
		crash();
	}
}
示例#2
0
/*
 * Open input file with given define for C-preprocessor
 */
static void
open_input(const char *infile, const char *define)
{
	int pd[2];
	int usevp;

	infilename = (infile == NULL) ? "<stdin>" : infile;
	pipe(pd);
	switch (childpid = fork()) {
	case 0:
		usevp = find_cpp();
		putarg(0, CPP);
		putarg(1, CPPFLAGS);
		addarg(define);
		if (infile)
			addarg(infile);
		addarg(NULL);
		close(1);
		dup2(pd[1], 1);
		close(pd[0]);
		if (usevp)
		    execvp(arglist[0], arglist);
		else
		    execv(arglist[0], arglist);
		err(1, "execv(%s)", arglist[0]);
	case -1:
		err(1, "fork");
	}
	close(pd[1]);
	fin = fdopen(pd[0], "r");
	if (fin == NULL) {
		warn("%s", infilename);
		crash();
	}
}
示例#3
0
int
main(int argc, char **argv) {
	extern int	optind;
	extern char	*optarg;
	int	ch;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while ((ch = getopt(argc, argv, "0123456789yli:f:h:t:")) != -1)
		switch((char)ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (!maxrec)
				maxrec = atol(argv[optind - 1] + 1);
			break;
		case 'f':
			file = optarg;
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'y':
			doyear = 1;
			break;
		case 'l':
			dolong = 1;
			break;
		case 'i':
			addarg(INET_TYPE, optarg);
			break;
		case '?':
		default:
			fputs(_("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n"), stderr);
			exit(1);
		}
	for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
		/* code to allow "last p5" to work */
		addarg(TTY_TYPE, ttyconv(*argv));
#endif
		addarg(USER_TYPE, *argv);
	}
	wtmp();
	exit(0);
}
示例#4
0
static void
process_args (int *p_argc, char *argv[])
{
  int i;

  for (i = 1; i < *p_argc; i++)
    {
      if (strlen (argv[i]) < 2)
	continue;

      if (strncmp (argv[i], "-I", 2) == 0)
	{
	  char *ptr;
	  int new_len, search_dirs_len;

	  ptr = to_host_dir_spec (&argv[i][2]);
	  new_len = strlen (ptr);
	  search_dirs_len = strlen (search_dirs);

	  search_dirs = xrealloc (search_dirs, search_dirs_len + new_len + 2);
	  if (search_dirs_len > 0)
	    strcat (search_dirs, PATH_SEPARATOR_STR);
	  strcat (search_dirs, ptr);
	}
      else if (strncmp (argv[i], "-D", 2) == 0)
	{
	  char *ptr;
	  int new_len, defines_len;

	  ptr = &argv[i][2];
	  new_len = strlen (ptr);
	  defines_len = strlen (defines);

	  defines = xrealloc (defines, defines_len + new_len + 4);
	  if (defines_len > 0)
	    strcat (defines, ",");

	  strcat (defines, "\"");
	  strcat (defines, ptr);
	  strcat (defines, "\"");
	}
      else if (strcmp (argv[i], "-v") == 0)
	verbose = 1;
      else if (strcmp (argv[i], "-g0") == 0)
	addarg ("/nodebug");
      else if (strcmp (argv[i], "-O0") == 0)
	addarg ("/noopt");
      else if (strncmp (argv[i], "-g", 2) == 0)
	addarg ("/debug");
      else if (strcmp (argv[i], "-E") == 0)
	addarg ("/preprocess");
      else if (strcmp (argv[i], "-save-temps") == 0)
	save_temps = 1;
    }
}
示例#5
0
文件: mtnexec.c 项目: kizkoh/mtnd
ARG readargline(int f, ARG arg)
{
  char c;
  int  r;
  int  len = 0;
  static char *buff = NULL;

  if(!arg){
    return(NULL);
  }
  if(!buff){
    buff = malloc(ctx->arg_max);
  }else{
    memset(buff, 0, ctx->arg_max);
  }
  while(is_loop){
    if(!(r = read(f, &c, 1))){
      // EOF
      if(len){
        break;
      }
      errno = 0;
      clrarg(arg);
      return(NULL);
    }
    if(r == -1){
      if(errno == EINTR){
        errno = 0;
        continue;
      }
      mtnlogger(mtn, 0, "[error] %s: %s\n", __func__, strerror(errno));
      clrarg(arg);
      return(NULL);
    }
    if(c == 0 || c == '\n'){
      if(!len){
        continue;
      }
      break;
    }
    if(is_delim(c)){
      if(len){
        buff[len] = 0;
        arg = addarg(arg, buff);
        len = 0;
      }
      continue;
    }
    buff[len++] = c;
  }
  buff[len] = 0;
  return(is_loop ? addarg(arg, buff) : clrarg(arg));
}
示例#6
0
static void
process(void)
{
	struct iblok	*ip;
	char	*arg;
	long	linecnt = 0;

	ip = ib_alloc(0, 0);
	if (iflag) {
		iflen = strlen(iflag);
		while ((arg = nextarg(ip, &linecnt)) != NULL) {
			if (eflag && *eflag && strcmp(arg, eflag) == 0)
				break;
			insert(arg);
		}
	} else {
		do {
			arg = nextarg(ip, &linecnt);
			if (arg && eflag && *eflag && strcmp(arg, eflag) == 0)
				arg = NULL;
			addarg(arg, lflag && lflag == linecnt ?
					linecnt = 0, 1 : 0);
		} while (arg != NULL);
	}
}
示例#7
0
文件: c89.c 项目: aosm/gcc_select
/* Add command line macro def (-Dblah) in the argument list.
   If it is was undefined earlier than do not add.  Radar 3762036.  */
void
add_def (const char *item)
{
  int i;
  char *updated_def;
  if (strlen (item) > 2)
    for (i = 0; i < undef_nargs; i++)
      {
	if (strcmp (item, undef_args[i]) == 0)
	  return;
	else {
	  int undef_len = strlen (undef_args[i]);
	  int def_len = strlen (item);
	  if (undef_len < def_len) {
	    const char *p = item + undef_len;
	    if (*p == '=') {
	      if (strncmp (item, undef_args[i], undef_len) == 0)
		return;
	    }
	  }
	    
	}
      }
  updated_def = (char *) malloc (strlen (item) + 3);
  sprintf (updated_def,"-D%s",item);
  addarg (updated_def);
}
示例#8
0
文件: c89.c 项目: aosm/gcc_select
/* Combine item1 and item2 and used them as one argument.
   This is used to combine "-O" with "1" to make "-O1".  */
void
combine_and_addarg (const char *item1, const char *item2)
{
  char *item = (char *) malloc (sizeof (char) * (strlen(item1) + strlen(item2) + 1));
  strcpy (item, item1);
  strcat (item, item2);
  addarg (item);
}
示例#9
0
static void addarg(vector<char> &argstr, const char *name, const char *val)
{
    addarg(argstr, name);
    bool space = strchr(val, ' ')!=NULL;
    if(space) argstr.add('"');
    argstr.put(val, strlen(val));
    if(space) argstr.add('"');
}
示例#10
0
文件: c89.c 项目: aosm/gcc_select
void
addlib(const char *lib)
{

	if (strcmp(lib, "pthread") == 0)
		/* pthread functionality is in libc. */
                ;
	else if (strcmp(lib, "rt") == 0)
		/* librt functionality is in libc or unimplemented. */
		;
	else if (strcmp(lib, "xnet") == 0)
		/* xnet functionality is in libc. */
		;
	else {
		addarg("-l");
		addarg(lib);
	}
}
示例#11
0
文件: c99.c 项目: 2asoft/freebsd
static void
addlib(const char *lib)
{

	if (strcmp(lib, "pthread") == 0)
		/* FreeBSD's gcc uses -pthread instead of -lpthread. */
		addarg("-pthread");
	else if (strcmp(lib, "rt") == 0)
		/* librt functionality is in libc or unimplemented. */
		;
	else if (strcmp(lib, "xnet") == 0)
		/* xnet functionality is in libc. */
		;
	else {
		addarg("-l");
		addarg(lib);
	}
}
/* Combine item1 and item2 and used them as one argument.
   This is used to combine "-O" with "1" to make "-O1".  */
void
combine_and_addarg (const char *item1, const char *item2)
{
  char *item = (char *) malloc (sizeof (char) * (strlen(item1) + strlen(item2) + 1));
  if (item == NULL)
    err (EX_OSERR, "malloc");
  strcpy (item, item1);
  strcat (item, item2);
  addarg (item);
}
示例#13
0
// Create an Optarg from its members and push it onto the array
static void addarg(
    getoopt::Arg_List& list,
    const String& name,
    Optarg::opttype type,
    const String& value)
{
    Optarg* o = new Optarg(name, type, value);
    addarg(list, *o);
    delete o;
}
示例#14
0
// Take an array of arguments and append it to another
static void copyargs(
    getoopt::Arg_List& out,
    const getoopt::Arg_List& in)
{
    Uint32 size = in.size();
    for (Uint32 i = 0; i < size; i++)
    {
        addarg(out, in[i]);
    }
}
示例#15
0
文件: mtnexec.c 项目: kizkoh/mtnd
ARG cmdargs(MTNJOB *job)
{
  int i;
  ARG cmd = newarg(0);
  if(job->args){
    for(i=0;job->args[i];i++){
      if(job->conv){
        cmd = addarg(cmd, convarg(newstr(job->args[i]), job));
      }else{
        cmd = addarg(cmd, newstr(job->args[i]));
      }
    }
  }
  if(!job->conv && job->argl){
    for(i=0;job->argl[i];i++){
      cmd = addarg(cmd, job->argl[i]);
    }
  }
  return(cmd);
}
示例#16
0
/*
 * Open input file with given define for C-preprocessor 
 */
static void
open_input(char *infile, char *define)
{
	int pd[2];

	infilename = (infile == NULL) ? "<stdin>" : infile;
	(void) pipe(pd);
	switch (fork()) {
	case 0:
		putarg(0, "cpp");
		putarg(1, CPPFLAGS);
		addarg(define);
		addarg(infile);
		addarg((char *)NULL);
		(void) close(1);
		(void) dup2(pd[1], 1);
		(void) close(pd[0]);
		if (cppDefined)
			execv(CPP, arglist);
		else {
			execvp("cpp", arglist);
			if (errno == ENOENT)
				execvp(SVR4_CPP, arglist);
			if (errno == ENOENT)
				execvp(SUNOS_CPP, arglist);
		}
		perror("execv");
		exit(1);
	case -1:
		perror("fork");
		exit(1);
	}
	(void) close(pd[1]);
	fin = fdopen(pd[0], "r");
	if (fin == NULL) {
		f_print(stderr, "%s: ", cmdname);
		perror(infilename);
		crash();
	}
}
示例#17
0
文件: c99.c 项目: 2asoft/freebsd
int
main(int argc, char *argv[])
{
	int ch, i;

	args = NULL;
	cargs = nargs = 0;

	while ((ch = getopt(argc, argv, "cD:EgI:L:o:O:sU:l:")) != -1) {
		if (ch == 'l') {
			/* Gone too far. Back up and get out. */
			if (argv[optind - 1][0] == '-')
				optind -= 1;
			else
				optind -= 2;
			break;
		} else if (ch == '?')
			usage();
	}

	addarg("/usr/bin/cc");
	addarg("-std=iso9899:1999");
	addarg("-pedantic");
	for (i = 1; i < optind; i++)
		addarg(argv[i]);
	while (i < argc) {
		if (strncmp(argv[i], "-l", 2) == 0) {
			if (argv[i][2] != '\0')
				addlib(argv[i++] + 2);
			else {
				if (argv[++i] == NULL)
					usage();
				addlib(argv[i++]);
			}
		} else
			addarg(argv[i++]);
	}
	execv("/usr/bin/cc", args);
	err(1, "/usr/bin/cc");
}
示例#18
0
文件: mtnexec.c 项目: kizkoh/mtnd
ARG cpconvarg(ARG a, MTNJOB *j)
{
  int i;
  ARG r = newarg(0);
  if(!a){
    return(r);
  }
  for(i=0;a[i];i++){
    r = addarg(r, a[i]);
    r[i] = convarg(r[i], j);
  }
  return(r);
}
示例#19
0
static void
preprocess_args (int *p_argc, char *argv[])
{
  int i;

  for (i = 1; i < *p_argc; i++)
    {
      if (strcmp (argv[i], "-o") == 0)
	{
	  char *buff, *ptr;

	  i++;
	  ptr = to_host_file_spec (argv[i]);
	  objfilename = xstrdup (ptr);
	  buff = concat ("/obj=", ptr, NULL);
	  addarg (buff);
	}
    }
}
示例#20
0
文件: list.c 项目: Denis2222/ft_ls
void	listdiranalyse(t_ls *ls, t_arg *arg, struct dirent *ent)
{
    struct stat		filestat;
    t_ent			*ment;
    char			*lpath;
    char			*lpath2;

    lpath = ft_strjoin("/", ent->d_name);
    lpath2 = ft_strjoin(arg->path, lpath);
    if (lstat(lpath2, &filestat) == 0)
    {
        ment = newent(ent->d_name, &filestat);
        arg->ent = addent(&(arg->ent), ment);
        if (!ft_strequ(ent->d_name, ".") && !ft_strequ(ent->d_name, ".."))
        {
            if ((ent->d_type == 4 || ent->d_type == 0) && ls->opts['R'])
            {
                arg->sub = addarg(&arg->sub, newarg(lpath2));
            }
        }
    }
    ft_strdel(&lpath2);
    ft_strdel(&lpath);
}
示例#21
0
文件: last.c 项目: Hooman3/minix
int
main(int argc, char *argv[])
{
	int ch;
	char *p;
	const char *file = NULL;
	int namesize = UT_NAMESIZE;
	int linesize = UT_LINESIZE;
	int hostsize = UT_HOSTSIZE;
	int numeric = 0;

	maxrec = -1;

	while ((ch = getopt(argc, argv, "0123456789f:H:h:L:nN:Tt:x")) != -1)
		switch (ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (maxrec == -1) {
				p = argv[optind - 1];
				if (p[0] == '-' && p[1] == ch && !p[2])
					maxrec = atol(++p);
				else if (optind < argc)
					maxrec = atol(argv[optind] + 1);
				else
					usage();
				if (!maxrec)
					return 0;
			}
			break;
		case 'f':
			file = optarg;
			if ('\0' == file[0])
				usage();
			break;
		case 'H':
			hostsize = atoi(optarg);
			if (hostsize < 1)
				usage();
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 'L':
			linesize = atoi(optarg);
			if (linesize < 1)
				usage();
			break;
		case 'N':
			namesize = atoi(optarg);
			if (namesize < 1)
				usage();
			break;
		case 'n':
			numeric = 1;
			break;
		case 'T':
			fulltime = 1;
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'x':
			xflag = 1;
			break;
		case '?':
		default:
			usage();
		}

	if (argc) {
		setlinebuf(stdout);
		for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
			/* code to allow "last p5" to work */
			addarg(TTY_TYPE, ttyconv(*argv));
#endif
			addarg(USER_TYPE, *argv);
		}
	}
	if (file == NULL) {
#ifdef SUPPORT_UTMPX
		if (access(_PATH_WTMPX, R_OK) == 0)
			file = _PATH_WTMPX;
		else
#endif
#ifdef SUPPORT_UTMP
		if (access(_PATH_WTMP, R_OK) == 0)
			file = _PATH_WTMP;
#endif
		if (file == NULL)
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
			errx(EXIT_FAILURE, "Cannot access `%s' or `%s'", _PATH_WTMPX,
			    _PATH_WTMP);
#elif defined(SUPPORT_UTMPX)
			errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMPX);
#elif defined(SUPPORT_UTMP)
			errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMP);
#else
			errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
#endif
	}
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
	if (file[strlen(file) - 1] == 'x' || xflag)
		wtmpx(file, namesize, linesize, hostsize, numeric);
	else
		wtmp(file, namesize, linesize, hostsize, numeric);
#elif defined(SUPPORT_UTMPX)
	wtmpx(file, namesize, linesize, hostsize, numeric);
#elif defined(SUPPORT_UTMP)
	wtmp(file, namesize, linesize, hostsize, numeric);
#else
	errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
#endif
	exit(EXIT_SUCCESS);
}
示例#22
0
int
main (int argc, char **argv)
{
  int i;
  char cwdev [128], *devptr;
  int devlen;
  char *cwd = getcwd (0, 1024);

  devptr = strchr (cwd, ':');
  devlen = (devptr - cwd) + 1;
  strncpy (cwdev, cwd, devlen);
  cwdev [devlen] = '\0';

  search_dirs = xstrdup (system_search_dirs);
  defines = xstrdup (default_defines);

  addarg ("cc");
  preprocess_args (&argc , argv);
  process_args (&argc , argv);

  if (strlen (search_dirs) > 0)
    {
      addarg ("/include=(");
      addarg (search_dirs);
      addarg (")");
    }

  if (strlen (defines) > 0)
    {
      addarg ("/define=(");
      addarg (defines);
      addarg (")");
    }

  for (i = 1; i < argc; i++)
    {
      int arg_len = strlen (argv[i]);

      if (strcmp (argv[i], "-o") == 0)
	i++;
      else if (strcmp (argv[i], "-v" ) == 0
	       || strcmp (argv[i], "-E") == 0
	       || strcmp (argv[i], "-c") == 0
	       || strncmp (argv[i], "-g", 2 ) == 0
	       || strncmp (argv[i], "-O", 2 ) == 0
	       || strcmp (argv[i], "-save-temps") == 0
	       || (arg_len > 2 && strncmp (argv[i], "-I", 2) == 0)
	       || (arg_len > 2 && strncmp (argv[i], "-D", 2) == 0))
	;

      /* Unix style file specs and VMS style switches look alike, so assume
	 an arg consisting of one and only one slash, and that being first, is
	 really a switch.  */
      else if ((argv[i][0] == '/') && (strchr (&argv[i][1], '/') == 0))
	addarg (argv[i]);
      else
	{
	  /* Assume filename arg */
	  char buff [256], *ptr;

	  ptr = to_host_file_spec (argv[i]);
	  arg_len = strlen (ptr);

	  if (ptr[0] == '[')
	    sprintf (buff, "%s%s", cwdev, ptr);
	  else if (strchr (ptr, ':'))
	    sprintf (buff, "%s", ptr);
	  else
	    sprintf (buff, "%s%s", cwd, ptr);

	  ptr = xstrdup (buff);
	  addarg (ptr);
	}
    }

  addarg (NULL);

  if (verbose)
    {
      int i;

      for (i = 0; i < comp_arg_index; i++)
	printf ("%s ", comp_args [i]);

      putchar ('\n');
    }

  {
    int i;
    int len = 0;

    for (i = 0; comp_args[i]; i++)
      len = len + strlen (comp_args[i]) + 1;

    {
      char *allargs = (char *) alloca (len + 1);
      Descr cmd;
      int status;
      int status1 = 1;

      for (i = 0; i < len + 1; i++)
	allargs [i] = 0;

      for (i = 0; comp_args [i]; i++)
	{
	  strcat (allargs, comp_args [i]);
	  strcat (allargs, " ");
	}

      cmd.adr = allargs;
      cmd.len = len;
      cmd.mbz = 0;

      i = LIB$SPAWN (&cmd, 0, 0, 0, 0, 0, &status);

      if ((i & 1) != 1)
	{
	  LIB$SIGNAL (i);
	  exit (1);
	}

      if ((status & 1) == 1 && (status1 & 1) == 1)
	exit (0);

      exit (1);
    }
  }
}
示例#23
0
int wizardmain(int argc, char **argv)
{
    const char *outfile = NULL, *relpath = NULL;
    for(int i = 1; i < argc; i++)
    {
        if(argv[i][0] == '-') continue;
        if(!outfile) outfile = argv[i];
        else if(!relpath) relpath = argv[i];
    }
    if(!outfile || !relpath)
    {
        printf("invalid arguments specified!\n");
        printf("usage: ac_server <outfile> <relbinarypath>\n");
        return EXIT_FAILURE;
    }

    printf("The AssaultCube Server Wizard\n\n");
    printf("Before setting up a new server, please ensure you've read the rules at:\n"
           "\thttp://masterserver.cubers.net/rules.html\n\n");
    printf("You will also need to ensure that the UDP port you choose is open.\n"
           "Whatever port you choose, you will need to forward that port, plus one port after that.\n"
           "If you're having issues, use and forward the default ports 28763 and 28764\n"
           "Use http://www.portforward.com for guidance.\n\n");
    printf("Now to specify some optional settings for your server.\n"
           "The default settings will be used if you leave the fields blank.\n"
           "If you're unsure about what to specify for the settings, leave the field blank.\n\n"
           "Read http://assault.cubers.net/docs/commandline.html for a description of these settings.\n\n");

    vector<char> argstr;
    readarg(argstr, "Server description", "-n");
    readarg(argstr, "Message of the day", "-o");
    readarg(argstr, "Maximum clients (No more than 20 allowed!)", "-c");
    readarg(argstr, "Administrator password", "-x");
    readarg(argstr, "Server port", "-f");

    printf("\nPrivate server settings:\n"
           "------------------------\n");
    string ispub = "";
    readarg("Public server (Yes/No)?", ispub, sizeof(ispub));
    if(toupper(ispub[0]) == 'N') addarg(argstr, "-mlocalhost");
    string cmds = "";
    readarg(argstr, "Player password", "-p");

    readarg("\nAdditional server switches", cmds, sizeof(cmds));
    if(cmds[0]) addarg(argstr, cmds);

#ifdef WIN32

    string wsname = "", wsdisplayname = "";
    readarg("win service name", wsname, sizeof(wsname));
    if(wsname[0])
        readarg("win service display", wsdisplayname, sizeof(wsdisplayname));

#endif

    printf("\nWriting your configuration to %s ... ", outfile); fflush(stdout);

    argstr.add('\0');

    FILE *script = fopen(outfile, "w");
    if(!script)
    {
        printf("Failed!\n");
        return EXIT_FAILURE;
    }

#ifdef WIN32
        fprintf(script, "%s%s\npause\n", relpath, argstr.getbuf());
#elif __GNUC__
        fprintf(script, "#!/bin/sh\n%s%s\n", relpath, argstr.getbuf());
#endif
    fclose(script);

    printf("Done\n\n");
    printf("Note: You can start %s directly the next time you want to use the same configuration to start the server.\n\n", outfile);

#ifdef WIN32

    if(wsname[0])
    {
        if(!wsdisplayname[0]) copystring(wsdisplayname, wsname);

        printf("Installing the AC Server as windows service ... "); fflush(stdout);

        vector<char> path;
        databuf<char> cwd = path.reserve(MAX_PATH);
        if(!_getcwd(cwd.buf, MAX_PATH))
        {
            printf("Failed!\n");
            printf("Could not get current working directory: %u\n", (uint)GetLastError());
            return EXIT_FAILURE;
        }
        path.advance(strlen(cwd.buf));
        path.add('\\');
        path.put(relpath, strlen(relpath));
        path.put(" -S", 3);
        path.put(wsname, strlen(wsname));
        path.add(' ');
        path.put(argstr.getbuf(), argstr.length());

        winserviceinstaller installer(wsname, wsdisplayname, path.getbuf());

        int r;
        if(!installer.OpenManger())
        {
            printf("Failed!\n");
            printf("Could not open the Service Control Manager: %u\n", (uint)GetLastError());
            installer.CloseManager();
            return EXIT_FAILURE;
        }

        if((r = installer.IsInstalled()) != 0)
        {
            printf("Failed!\n");
            if(r == -1) printf("Error accessing the Service Control Manager\n");
            else if(r == 1) printf("A windows service with this name (%s) is already installed: %u\n", wsname, (uint)GetLastError());
            return EXIT_FAILURE;
        }

        if((r = installer.Install()) != 1)
        {
            printf("Failed!\n");
            if(r == -1) printf("Error accessing the Service Control Manager\n");
            else if(r == 0) printf("Could not create the new windows service: %u\n", (uint)GetLastError());
            return EXIT_FAILURE;
        }

        printf("Done\n\n");
        printf("Note: You can now manage your AC server using services.msc and sc.exe\n\n");
    }

#endif

    printf("Please press ENTER now to start your server...\n");
    fgetc(stdin);
    printf("Starting the AC server ...\n");
    argstr.insert(0, relpath, strlen(relpath));
    system(argstr.getbuf());

    return EXIT_SUCCESS;
}
示例#24
0
static void readarg(vector<char> &argstr, const char *desc, const char *name)
{
    string val = "";
    readarg(desc, val, sizeof(val));
    if(val[0]) addarg(argstr, name, val);
}
示例#25
0
int
r_ies(				/* convert an IES luminaire file */
	int	ac,
	char	**av
)
{
	int	xa0 = 2;
	char	combuf[128];
	char	fname[48];
	char	*oname;
	register char	*op;
	register int	i;
					/* check argument count */
	if (ac < 2)
		return(MG_EARGC);
					/* construct output file name */
	if ((op = strrchr(av[1], '/')) != NULL)
		op++;
	else
		op = av[1];
	(void)strcpy(fname, op);
	if ((op = strrchr(fname, '.')) == NULL)
		op = fname + strlen(fname);
	(void)strcpy(op, ".rad");
					/* see if we need to run ies2rad */
	if (access(fname, 0) == -1) {
		(void)strcpy(combuf, "ies2rad");/* build ies2rad command */
		op = combuf + 7;		/* get -m option (first) */
		if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
			if (!isflt(av[xa0+1]))
				return(MG_ETYPE);
			op = addarg(addarg(op, "-m"), av[xa0+1]);
			xa0 += 2;
		}
		*op++ = ' ';			/* build IES filename */
		i = 0;
		if (mg_file != NULL &&
				(oname = strrchr(mg_file->fname,'/')) != NULL) {
			i = oname - mg_file->fname + 1;
			(void)strcpy(op, mg_file->fname);
		}
		(void)strcpy(op+i, av[1]);
		if (access(op, 0) == -1)	/* check for file existence */
			return(MG_ENOFILE);
		system(combuf);			/* run ies2rad */
		if (access(fname, 0) == -1)	/* check success */
			return(MG_EINCL);
	}
	printf("\n!xform");			/* put out xform command */
	oname = object();
	if (*oname) {
		printf(" -n ");
		for (op = oname; op[1]; op++)	/* remove trailing separator */
			putchar(*op);
	}
	for (i = xa0; i < ac; i++)
		printf(" %s", av[i]);
	if (ac > xa0 && xf_argc > 0)
		printf(" -i 1");
	for (i = 0; i < xf_argc; i++)
		printf(" %s", xf_argv[i]);
	printf(" %s\n", fname);
	return(MG_OK);
}
示例#26
0
static          uid_t
pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer)
{
	struct group   *grp;
	gid_t           gid = (uid_t) - 1;
	struct carg    *a_gid = getarg(args, 'g');

	/*
	 * If no arg given, see if default can help out
	 */
	if (a_gid == NULL && cnf->default_group && *cnf->default_group)
		a_gid = addarg(args, 'g', cnf->default_group);

	/*
	 * Check the given gid, if any
	 */
	SETGRENT();
	if (a_gid != NULL) {
		if ((grp = GETGRNAM(a_gid->val)) == NULL) {
			gid = (gid_t) atol(a_gid->val);
			if ((gid == 0 && !isdigit((unsigned char)*a_gid->val)) || (grp = GETGRGID(gid)) == NULL)
				errx(EX_NOUSER, "group `%s' is not defined", a_gid->val);
		}
		gid = grp->gr_gid;
	} else if ((grp = GETGRNAM(nam)) != NULL &&
	    (grp->gr_mem == NULL || grp->gr_mem[0] == NULL)) {
		gid = grp->gr_gid;  /* Already created? Use it anyway... */
	} else {
		struct cargs    grpargs;
		char            tmp[32];

		LIST_INIT(&grpargs);
		addarg(&grpargs, 'n', nam);

		/*
		 * We need to auto-create a group with the user's name. We
		 * can send all the appropriate output to our sister routine
		 * bit first see if we can create a group with gid==uid so we
		 * can keep the user and group ids in sync. We purposely do
		 * NOT check the gid range if we can force the sync. If the
		 * user's name dups an existing group, then the group add
		 * function will happily handle that case for us and exit.
		 */
		if (GETGRGID(prefer) == NULL) {
			sprintf(tmp, "%lu", (unsigned long) prefer);
			addarg(&grpargs, 'g', tmp);
		}
		if (getarg(args, 'N'))
		{
			addarg(&grpargs, 'N', NULL);
			addarg(&grpargs, 'q', NULL);
			gid = pw_group(cnf, M_NEXT, &grpargs);
		}
		else
		{
			pw_group(cnf, M_ADD, &grpargs);
			if ((grp = GETGRNAM(nam)) != NULL)
				gid = grp->gr_gid;
		}
		a_gid = LIST_FIRST(&grpargs);
		while (a_gid != NULL) {
			struct carg    *t = LIST_NEXT(a_gid, list);
			LIST_REMOVE(a_gid, list);
			a_gid = t;
		}
	}
	ENDGRENT();
	return gid;
}
示例#27
0
文件: f77.c 项目: JamesLinus/pcc
int
main(int argc, char **argv)
{
	int i, c, status;
	char *s;
	char fortfile[20], *t;
	char buff[100];

	diagfile = stderr;

	sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
	sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
	enbint(intrupt);

	pid = getpid();
	crfnames();

	loadargs = (char **)calloc(1, (argc + 20) * sizeof(*loadargs));
	if (!loadargs)
		fatal1("out of memory");
	loadp = loadargs;

	--argc;
	++argv;

	while(argc>0 && argv[0][0]=='-' && argv[0][1]!='\0') {
		for(s = argv[0]+1 ; *s ; ++s)
			switch(*s) {
			case 'T':  /* use special passes */
				switch(*++s) {
				case '1':
					fcom = s+1; goto endfor;
				case 'a':
					asmname = s+1; goto endfor;
				case 'l':
					ldname = s+1; goto endfor;
				case 'm':
					macroname = s+1; goto endfor;
				default:
					fatal1("bad option -T%c", *s);
				}
				break;

			case 'w': /* F66 warn or no warn */
				addarg(ffary, &ffmax, s-1);
				break;

			case 'q':
				/*
				 * Suppress printing of procedure names during
				 * compilation.
				 */
				addarg(ffary, &ffmax, s-1);
				break;

			copyfflag:
			case 'u':
			case 'U':
			case 'M':
			case '1':
			case 'C':
				addarg(ffary, &ffmax, s-1);
				break;

			case 'O':
				optimflag = YES;
				addarg(ffary, &ffmax, s-1);
				break;

			case 'm':
				if(s[1] == '4')
					++s;
				macroflag = YES;
				break;

			case 'S':
				saveasmflag = YES;

			case 'c':
				loadflag = NO;
				break;

			case 'v':
				verbose = YES;
				break;

			case 'd':
				debugflag = YES;
				goto copyfflag;

			case 'p':
				profileflag = YES;
				goto copyfflag;

			case 'o':
				if(!strcmp(s, "onetrip")) {
					addarg(ffary, &ffmax, s-1);
					goto endfor;
				}
				oflag = 1;
				aoutname = *++argv;
				--argc;
				break;

			case 'F':
				fortonly = YES;
				loadflag = NO;
				break;

			case 'I':
				if(s[1]=='2' || s[1]=='4' || s[1]=='s')
					goto copyfflag;
				fprintf(diagfile, "invalid flag -I%c\n", s[1]);
				done(1);

			case 'l':	/* letter ell--library */
				s[-1] = '-';
				*loadp++ = s-1;
				goto endfor;

			case 'E':	/* EFL flag argument */
				while(( *eflagp++ = *++s))
					;
				*eflagp++ = ' ';
				goto endfor;
			case 'R':
				while(( *rflagp++ = *++s ))
					;
				*rflagp++ = ' ';
				goto endfor;
			default:
				lflag[1] = *s;
				*loadp++ = copyn(strlen(lflag), lflag);
				break;
			}
endfor:
	--argc;
	++argv;
	}

	if (verbose)
		fprintf(stderr, xxxvers);

	if (argc == 0)
		errorx("No input files");

#ifdef mach_pdp11
	if(nofloating)
		*loadp++ = (profileflag ? NOFLPROF : NOFLFOOT);
	else
#endif

	for(i = 0 ; i<argc ; ++i)
		switch(c =  dotchar(infname = argv[i]) ) {
		case 'r':	/* Ratfor file */
		case 'e':	/* EFL file */
			if( unreadable(argv[i]) )
				break;
			s = fortfile;
			t = lastfield(argv[i]);
			while(( *s++ = *t++))
				;
			s[-2] = 'f';

			if(macroflag) {
				snprintf(buff, sizeof(buff), "%s %s >%s",
				    macroname, infname, prepfname);
				if(sys(buff)) {
					rmf(prepfname);
					break;
				}
				infname = prepfname;
			}

			if(c == 'e')
				snprintf(buff, sizeof(buff), "efl %s %s >%s",
				    eflags, infname, fortfile);
			else
				snprintf(buff, sizeof(buff), "ratfor %s %s >%s",
				    rflags, infname, fortfile);
			status = sys(buff);
			if(macroflag)
				rmf(infname);
			if(status) {
				loadflag = NO;
				rmf(fortfile);
				break;
			}

			if( ! fortonly ) {
				infname = argv[i] = lastfield(argv[i]);
				*lastchar(infname) = 'f';
	
				if( dofort(argv[i]) )
					loadflag = NO;
				else	{
					if( nodup(t = setdoto(argv[i])) )
						*loadp++ = t;
					rmf(fortfile);
				}
			}
			break;

		case 'f':	/* Fortran file */
		case 'F':
			if( unreadable(argv[i]) )
				break;
			if( dofort(argv[i]) )
				loadflag = NO;
			else if( nodup(t=setdoto(argv[i])) )
				*loadp++ = t;
			break;

		case 'c':	/* C file */
		case 's':	/* Assembler file */
			if( unreadable(argv[i]) )
				break;
			fprintf(diagfile, "%s:\n", argv[i]);
			snprintf(buff, sizeof(buff), "cc -c %s", argv[i]);
			if( sys(buff) )
				loadflag = NO;
			else
				if( nodup(t = setdoto(argv[i])) )
					*loadp++ = t;
			break;

		case 'o':
			if( nodup(argv[i]) )
				*loadp++ = argv[i];
			break;

		default:
			if( ! strcmp(argv[i], "-o") )
				aoutname = argv[++i];
			else
				*loadp++ = argv[i];
			break;
		}

	if(loadflag)
		doload(loadargs, loadp);
	done(0);
	return 0;
}
示例#28
0
int
main(int argc, char *argv[])
{
	const char *errstr;
	int ch, lastch = '\0', newarg = 1, prevoptind = 1;

	while ((ch = getopt(argc, argv, "0123456789cf:h:n:st:d:T")) != -1) {
		switch (ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (newarg || !isdigit(lastch))
				maxrec = 0;
			else if (maxrec > INT_MAX / 10)
				usage();
			maxrec = (maxrec * 10) + (ch - '0');
			break;
		case 'c':
			calculate++;
			break;
		case 'f':
			file = optarg;
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 'n':
			maxrec = strtonum(optarg, 0, LONG_MAX, &errstr);
			if (errstr != NULL)
				errx(1, "number of lines is %s: %s", errstr,
				    optarg);
			if (maxrec == 0)
				exit(0);
			break;
		case 's':
			seconds++;
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'd':
			snaptime = dateconv(optarg);
			break;
		case 'T':
			fulltime = 1;
			break;
		default:
			usage();
		}
		lastch = ch;
		newarg = optind != prevoptind;
		prevoptind = optind;
	}
	if (maxrec == 0)
		exit(0);

	if (argc) {
		setlinebuf(stdout);
		for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
			/* code to allow "last p5" to work */
			addarg(TTY_TYPE, ttyconv(*argv));
#endif
			addarg(USER_TYPE, *argv);
		}
	}

	checkargs();
	wtmp();
	exit(0);
}
示例#29
0
int
pw_user(struct userconf * cnf, int mode, struct cargs * args)
{
	int	        rc, edited = 0;
	char           *p = NULL;
	char					 *passtmp;
	struct carg    *a_name;
	struct carg    *a_uid;
	struct carg    *arg;
	struct passwd  *pwd = NULL;
	struct group   *grp;
	struct stat     st;
	char            line[_PASSWORD_LEN+1];
	FILE	       *fp;
	char *dmode_c;
	void *set = NULL;

	static struct passwd fakeuser =
	{
		NULL,
		"*",
		-1,
		-1,
		0,
		"",
		"User &",
		"/nonexistent",
		"/bin/sh",
		0
#if defined(__FreeBSD__)
		,0
#endif
	};


	/*
	 * With M_NEXT, we only need to return the
	 * next uid to stdout
	 */
	if (mode == M_NEXT)
	{
		uid_t next = pw_uidpolicy(cnf, args);
		if (getarg(args, 'q'))
			return next;
		printf("%ld:", (long)next);
		pw_group(cnf, mode, args);
		return EXIT_SUCCESS;
	}

	/*
	 * We can do all of the common legwork here
	 */

	if ((arg = getarg(args, 'b')) != NULL) {
		cnf->home = arg->val;
	}

	if ((arg = getarg(args, 'M')) != NULL) {
		dmode_c = arg->val;
		if ((set = setmode(dmode_c)) == NULL)
			errx(EX_DATAERR, "invalid directory creation mode '%s'",
			    dmode_c);
		cnf->homemode = getmode(set, _DEF_DIRMODE);
		free(set);
	}

	/*
	 * If we'll need to use it or we're updating it,
	 * then create the base home directory if necessary
	 */
	if (arg != NULL || getarg(args, 'm') != NULL) {
		int	l = strlen(cnf->home);

		if (l > 1 && cnf->home[l-1] == '/')	/* Shave off any trailing path delimiter */
			cnf->home[--l] = '\0';

		if (l < 2 || *cnf->home != '/')		/* Check for absolute path name */
			errx(EX_DATAERR, "invalid base directory for home '%s'", cnf->home);

		if (stat(cnf->home, &st) == -1) {
			char	dbuf[MAXPATHLEN];

			/*
			 * This is a kludge especially for Joerg :)
			 * If the home directory would be created in the root partition, then
			 * we really create it under /usr which is likely to have more space.
			 * But we create a symlink from cnf->home -> "/usr" -> cnf->home
			 */
			if (strchr(cnf->home+1, '/') == NULL) {
				strcpy(dbuf, "/usr");
				strncat(dbuf, cnf->home, MAXPATHLEN-5);
				if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) {
					chown(dbuf, 0, 0);
					/*
					 * Skip first "/" and create symlink:
					 * /home -> usr/home
					 */
					symlink(dbuf+1, cnf->home);
				}
				/* If this falls, fall back to old method */
			}
			strlcpy(dbuf, cnf->home, sizeof(dbuf));
			p = dbuf;
			if (stat(dbuf, &st) == -1) {
				while ((p = strchr(p + 1, '/')) != NULL) {
					*p = '\0';
					if (stat(dbuf, &st) == -1) {
						if (mkdir(dbuf, _DEF_DIRMODE) == -1)
							goto direrr;
						chown(dbuf, 0, 0);
					} else if (!S_ISDIR(st.st_mode))
						errx(EX_OSFILE, "'%s' (root home parent) is not a directory", dbuf);
					*p = '/';
				}
			}
			if (stat(dbuf, &st) == -1) {
				if (mkdir(dbuf, _DEF_DIRMODE) == -1) {
				direrr:	err(EX_OSFILE, "mkdir '%s'", dbuf);
				}
				chown(dbuf, 0, 0);
			}
		} else if (!S_ISDIR(st.st_mode))
			errx(EX_OSFILE, "root home `%s' is not a directory", cnf->home);
	}

	if ((arg = getarg(args, 'e')) != NULL)
		cnf->expire_days = atoi(arg->val);

	if ((arg = getarg(args, 'y')) != NULL)
		cnf->nispasswd = arg->val;

	if ((arg = getarg(args, 'p')) != NULL && arg->val)
		cnf->password_days = atoi(arg->val);

	if ((arg = getarg(args, 'g')) != NULL) {
		if (!*(p = arg->val))	/* Handle empty group list specially */
			cnf->default_group = "";
		else {
			if ((grp = GETGRNAM(p)) == NULL) {
				if (!isdigit((unsigned char)*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL)
					errx(EX_NOUSER, "group `%s' does not exist", p);
			}
			cnf->default_group = newstr(grp->gr_name);
		}
	}
	if ((arg = getarg(args, 'L')) != NULL)
		cnf->default_class = pw_checkname((u_char *)arg->val, 0);

	if ((arg = getarg(args, 'G')) != NULL && arg->val) {
		int i = 0;

		for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
			if ((grp = GETGRNAM(p)) == NULL) {
				if (!isdigit((unsigned char)*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL)
					errx(EX_NOUSER, "group `%s' does not exist", p);
			}
			if (extendarray(&cnf->groups, &cnf->numgroups, i + 2) != -1)
				cnf->groups[i++] = newstr(grp->gr_name);
		}
		while (i < cnf->numgroups)
			cnf->groups[i++] = NULL;
	}

	if ((arg = getarg(args, 'k')) != NULL) {
		if (stat(cnf->dotdir = arg->val, &st) == -1 || !S_ISDIR(st.st_mode))
			errx(EX_OSFILE, "skeleton `%s' is not a directory or does not exist", cnf->dotdir);
	}

	if ((arg = getarg(args, 's')) != NULL)
		cnf->shell_default = arg->val;

	if ((arg = getarg(args, 'w')) != NULL)
		cnf->default_password = boolean_val(arg->val, cnf->default_password);
	if (mode == M_ADD && getarg(args, 'D')) {
		if (getarg(args, 'n') != NULL)
			errx(EX_DATAERR, "can't combine `-D' with `-n name'");
		if ((arg = getarg(args, 'u')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) {
			if ((cnf->min_uid = (uid_t) atoi(p)) == 0)
				cnf->min_uid = 1000;
			if ((p = strtok(NULL, " ,\t")) == NULL || (cnf->max_uid = (uid_t) atoi(p)) < cnf->min_uid)
				cnf->max_uid = 32000;
		}
		if ((arg = getarg(args, 'i')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) {
			if ((cnf->min_gid = (gid_t) atoi(p)) == 0)
				cnf->min_gid = 1000;
			if ((p = strtok(NULL, " ,\t")) == NULL || (cnf->max_gid = (gid_t) atoi(p)) < cnf->min_gid)
				cnf->max_gid = 32000;
		}

		arg = getarg(args, 'C');
		if (write_userconfig(arg ? arg->val : NULL))
			return EXIT_SUCCESS;
		warn("config update");
		return EX_IOERR;
	}

	if (mode == M_PRINT && getarg(args, 'a')) {
		int             pretty = getarg(args, 'P') != NULL;
		int		v7 = getarg(args, '7') != NULL;
		SETPWENT();
		while ((pwd = GETPWENT()) != NULL)
			print_user(pwd, pretty, v7);
		ENDPWENT();
		return EXIT_SUCCESS;
	}

	if ((a_name = getarg(args, 'n')) != NULL)
		pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, 0));
	a_uid = getarg(args, 'u');

	if (a_uid == NULL) {
		if (a_name == NULL)
			errx(EX_DATAERR, "user name or id required");

		/*
		 * Determine whether 'n' switch is name or uid - we don't
		 * really don't really care which we have, but we need to
		 * know.
		 */
		if (mode != M_ADD && pwd == NULL
		    && strspn(a_name->val, "0123456789") == strlen(a_name->val)
		    && *a_name->val) {
			(a_uid = a_name)->ch = 'u';
			a_name = NULL;
		}
	}

	/*
	 * Update, delete & print require that the user exists
	 */
	if (mode == M_UPDATE || mode == M_DELETE ||
	    mode == M_PRINT  || mode == M_LOCK   || mode == M_UNLOCK) {

		if (a_name == NULL && pwd == NULL)	/* Try harder */
			pwd = GETPWUID(atoi(a_uid->val));

		if (pwd == NULL) {
			if (mode == M_PRINT && getarg(args, 'F')) {
				fakeuser.pw_name = a_name ? a_name->val : "nouser";
				fakeuser.pw_uid = a_uid ? (uid_t) atol(a_uid->val) : -1;
				return print_user(&fakeuser,
						  getarg(args, 'P') != NULL,
						  getarg(args, '7') != NULL);
			}
			if (a_name == NULL)
				errx(EX_NOUSER, "no such uid `%s'", a_uid->val);
			errx(EX_NOUSER, "no such user `%s'", a_name->val);
		}

		if (a_name == NULL)	/* May be needed later */
			a_name = addarg(args, 'n', newstr(pwd->pw_name));

		/*
		 * The M_LOCK and M_UNLOCK functions simply add or remove
		 * a "*LOCKED*" prefix from in front of the password to
		 * prevent it decoding correctly, and therefore prevents
		 * access. Of course, this only prevents access via
		 * password authentication (not ssh, kerberos or any
		 * other method that does not use the UNIX password) but
		 * that is a known limitation.
		 */

		if (mode == M_LOCK) {
			if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0)
				errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name);
			passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str));
			if (passtmp == NULL)	/* disaster */
				errx(EX_UNAVAILABLE, "out of memory");
			strcpy(passtmp, locked_str);
			strcat(passtmp, pwd->pw_passwd);
			pwd->pw_passwd = passtmp;
			edited = 1;
		} else if (mode == M_UNLOCK) {
			if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) != 0)
				errx(EX_DATAERR, "user '%s' is not locked", pwd->pw_name);
			pwd->pw_passwd += sizeof(locked_str)-1;
			edited = 1;
		} else if (mode == M_DELETE) {
			/*
			 * Handle deletions now
			 */
			char            file[MAXPATHLEN];
			char            home[MAXPATHLEN];
			uid_t           uid = pwd->pw_uid;
			struct group    *gr;
			char            grname[LOGNAMESIZE];

			if (strcmp(pwd->pw_name, "root") == 0)
				errx(EX_DATAERR, "cannot remove user 'root'");

			if (!PWALTDIR()) {
				/*
				 * Remove opie record from /etc/opiekeys
		        	 */

				rmopie(pwd->pw_name);

				/*
				 * Remove crontabs
				 */
				snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name);
				if (access(file, F_OK) == 0) {
					sprintf(file, "crontab -u %s -r", pwd->pw_name);
					system(file);
				}
			}
			/*
			 * Save these for later, since contents of pwd may be
			 * invalidated by deletion
			 */
			sprintf(file, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
			strlcpy(home, pwd->pw_dir, sizeof(home));
			gr = GETGRGID(pwd->pw_gid);
			if (gr != NULL)
				strlcpy(grname, gr->gr_name, LOGNAMESIZE);
			else
				grname[0] = '\0';

			rc = delpwent(pwd);
			if (rc == -1)
				err(EX_IOERR, "user '%s' does not exist", pwd->pw_name);
			else if (rc != 0) {
				warn("passwd update");
				return EX_IOERR;
			}

			if (cnf->nispasswd && *cnf->nispasswd=='/') {
				rc = delnispwent(cnf->nispasswd, a_name->val);
				if (rc == -1)
					warnx("WARNING: user '%s' does not exist in NIS passwd", pwd->pw_name);
				else if (rc != 0)
					warn("WARNING: NIS passwd update");
				/* non-fatal */
			}

			grp = GETGRNAM(a_name->val);
			if (grp != NULL &&
			    (grp->gr_mem == NULL || *grp->gr_mem == NULL) &&
			    strcmp(a_name->val, grname) == 0)
				delgrent(GETGRNAM(a_name->val));
			SETGRENT();
			while ((grp = GETGRENT()) != NULL) {
				int i, j;
				char group[MAXLOGNAME];
				if (grp->gr_mem != NULL) {
					for (i = 0; grp->gr_mem[i] != NULL; i++) {
						if (!strcmp(grp->gr_mem[i], a_name->val)) {
							for (j = i; grp->gr_mem[j] != NULL; j++)
								grp->gr_mem[j] = grp->gr_mem[j+1];
							strlcpy(group, grp->gr_name, MAXLOGNAME);
							chggrent(group, grp);
						}
					}
				}
			}
			ENDGRENT();

			pw_log(cnf, mode, W_USER, "%s(%ld) account removed", a_name->val, (long) uid);

			if (!PWALTDIR()) {
				/*
				 * Remove mail file
				 */
				remove(file);

				/*
				 * Remove at jobs
				 */
				if (getpwuid(uid) == NULL)
					rmat(uid);

				/*
				 * Remove home directory and contents
				 */
				if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) {
					if (stat(home, &st) != -1) {
						rm_r(home, uid);
						pw_log(cnf, mode, W_USER, "%s(%ld) home '%s' %sremoved",
						       a_name->val, (long) uid, home,
						       stat(home, &st) == -1 ? "" : "not completely ");
					}
				}
			}
			return EXIT_SUCCESS;
		} else if (mode == M_PRINT)
			return print_user(pwd,
					  getarg(args, 'P') != NULL,
					  getarg(args, '7') != NULL);

		/*
		 * The rest is edit code
		 */
		if ((arg = getarg(args, 'l')) != NULL) {
			if (strcmp(pwd->pw_name, "root") == 0)
				errx(EX_DATAERR, "can't rename `root' account");
			pwd->pw_name = pw_checkname((u_char *)arg->val, 0);
			edited = 1;
		}

		if ((arg = getarg(args, 'u')) != NULL && isdigit((unsigned char)*arg->val)) {
			pwd->pw_uid = (uid_t) atol(arg->val);
			edited = 1;
			if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0)
				errx(EX_DATAERR, "can't change uid of `root' account");
			if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0)
				warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name);
		}

		if ((arg = getarg(args, 'g')) != NULL && pwd->pw_uid != 0) {	/* Already checked this */
			gid_t newgid = (gid_t) GETGRNAM(cnf->default_group)->gr_gid;
			if (newgid != pwd->pw_gid) {
				edited = 1;
				pwd->pw_gid = newgid;
			}
		}

		if ((arg = getarg(args, 'p')) != NULL) {
			if (*arg->val == '\0' || strcmp(arg->val, "0") == 0) {
				if (pwd->pw_change != 0) {
					pwd->pw_change = 0;
					edited = 1;
				}
			}
			else {
				time_t          now = time(NULL);
				time_t          expire = parse_date(now, arg->val);

				if (pwd->pw_change != expire) {
					pwd->pw_change = expire;
					edited = 1;
				}
			}
		}

		if ((arg = getarg(args, 'e')) != NULL) {
			if (*arg->val == '\0' || strcmp(arg->val, "0") == 0) {
				if (pwd->pw_expire != 0) {
					pwd->pw_expire = 0;
					edited = 1;
				}
			}
			else {
				time_t          now = time(NULL);
				time_t          expire = parse_date(now, arg->val);

				if (pwd->pw_expire != expire) {
					pwd->pw_expire = expire;
					edited = 1;
				}
			}
		}

		if ((arg = getarg(args, 's')) != NULL) {
			char *shell = shell_path(cnf->shelldir, cnf->shells, arg->val);
			if (shell == NULL)
				shell = "";
			if (strcmp(shell, pwd->pw_shell) != 0) {
				pwd->pw_shell = shell;
				edited = 1;
			}
		}

		if (getarg(args, 'L')) {
			if (cnf->default_class == NULL)
				cnf->default_class = "";
			if (strcmp(pwd->pw_class, cnf->default_class) != 0) {
				pwd->pw_class = cnf->default_class;
				edited = 1;
			}
		}

		if ((arg  = getarg(args, 'd')) != NULL) {
			if (strcmp(pwd->pw_dir, arg->val))
				edited = 1;
			if (stat(pwd->pw_dir = arg->val, &st) == -1) {
				if (getarg(args, 'm') == NULL && strcmp(pwd->pw_dir, "/nonexistent") != 0)
				  warnx("WARNING: home `%s' does not exist", pwd->pw_dir);
			} else if (!S_ISDIR(st.st_mode))
				warnx("WARNING: home `%s' is not a directory", pwd->pw_dir);
		}

		if ((arg = getarg(args, 'w')) != NULL &&
		    getarg(args, 'h') == NULL && getarg(args, 'H') == NULL) {
			login_cap_t *lc;

			lc = login_getpwclass(pwd);
			if (lc == NULL ||
			    login_setcryptfmt(lc, "sha512", NULL) == NULL)
				warn("setting crypt(3) format");
			login_close(lc);
			pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name);
			edited = 1;
		}

	} else {
		login_cap_t *lc;

		/*
		 * Add code
		 */

		if (a_name == NULL)	/* Required */
			errx(EX_DATAERR, "login name required");
		else if ((pwd = GETPWNAM(a_name->val)) != NULL)	/* Exists */
			errx(EX_DATAERR, "login name `%s' already exists", a_name->val);

		/*
		 * Now, set up defaults for a new user
		 */
		pwd = &fakeuser;
		pwd->pw_name = a_name->val;
		pwd->pw_class = cnf->default_class ? cnf->default_class : "";
		pwd->pw_uid = pw_uidpolicy(cnf, args);
		pwd->pw_gid = pw_gidpolicy(cnf, args, pwd->pw_name, (gid_t) pwd->pw_uid);
		pwd->pw_change = pw_pwdpolicy(cnf, args);
		pwd->pw_expire = pw_exppolicy(cnf, args);
		pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name);
		pwd->pw_shell = pw_shellpolicy(cnf, args, NULL);
		lc = login_getpwclass(pwd);
		if (lc == NULL || login_setcryptfmt(lc, "sha512", NULL) == NULL)
			warn("setting crypt(3) format");
		login_close(lc);
		pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name);
		edited = 1;

		if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0)
			warnx("WARNING: new account `%s' has a uid of 0 (superuser access!)", pwd->pw_name);
	}

	/*
	 * Shared add/edit code
	 */
	if ((arg = getarg(args, 'c')) != NULL) {
		char	*gecos = pw_checkname((u_char *)arg->val, 1);
		if (strcmp(pwd->pw_gecos, gecos) != 0) {
			pwd->pw_gecos = gecos;
			edited = 1;
		}
	}

	if ((arg = getarg(args, 'h')) != NULL ||
	    (arg = getarg(args, 'H')) != NULL) {
		if (strcmp(arg->val, "-") == 0) {
			if (!pwd->pw_passwd || *pwd->pw_passwd != '*') {
				pwd->pw_passwd = "*";	/* No access */
				edited = 1;
			}
		} else {
			int             fd = atoi(arg->val);
			int		precrypt = (arg->ch == 'H');
			int             b;
			int             istty = isatty(fd);
			struct termios  t;
			login_cap_t	*lc;

			if (istty) {
				if (tcgetattr(fd, &t) == -1)
					istty = 0;
				else {
					struct termios  n = t;

					/* Disable echo */
					n.c_lflag &= ~(ECHO);
					tcsetattr(fd, TCSANOW, &n);
					printf("%s%spassword for user %s:",
					     (mode == M_UPDATE) ? "new " : "",
					     precrypt ? "encrypted " : "",
					     pwd->pw_name);
					fflush(stdout);
				}
			}
			b = read(fd, line, sizeof(line) - 1);
			if (istty) {	/* Restore state */
				tcsetattr(fd, TCSANOW, &t);
				fputc('\n', stdout);
				fflush(stdout);
			}
			if (b < 0) {
				warn("-%c file descriptor", precrypt ? 'H' :
				    'h');
				return EX_IOERR;
			}
			line[b] = '\0';
			if ((p = strpbrk(line, "\r\n")) != NULL)
				*p = '\0';
			if (!*line)
				errx(EX_DATAERR, "empty password read on file descriptor %d", fd);
			if (precrypt) {
				if (strchr(line, ':') != NULL)
					return EX_DATAERR;
				pwd->pw_passwd = line;
			} else {
				lc = login_getpwclass(pwd);
				if (lc == NULL ||
				    login_setcryptfmt(lc, "sha512", NULL) == NULL)
					warn("setting crypt(3) format");
				login_close(lc);
				pwd->pw_passwd = pw_pwcrypt(line);
			}
			edited = 1;
		}
	}

	/*
	 * Special case: -N only displays & exits
	 */
	if (getarg(args, 'N') != NULL)
		return print_user(pwd,
				  getarg(args, 'P') != NULL,
				  getarg(args, '7') != NULL);

	if (mode == M_ADD) {
		edited = 1;	/* Always */
		rc = addpwent(pwd);
		if (rc == -1) {
			warnx("user '%s' already exists", pwd->pw_name);
			return EX_IOERR;
		} else if (rc != 0) {
			warn("passwd file update");
			return EX_IOERR;
		}
		if (cnf->nispasswd && *cnf->nispasswd=='/') {
			rc = addnispwent(cnf->nispasswd, pwd);
			if (rc == -1)
				warnx("User '%s' already exists in NIS passwd", pwd->pw_name);
			else
				warn("NIS passwd update");
			/* NOTE: we treat NIS-only update errors as non-fatal */
		}
	} else if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) {
		if (edited) {	/* Only updated this if required */
			rc = chgpwent(a_name->val, pwd);
			if (rc == -1) {
				warnx("user '%s' does not exist (NIS?)", pwd->pw_name);
				return EX_IOERR;
			} else if (rc != 0) {
				warn("passwd file update");
				return EX_IOERR;
			}
			if ( cnf->nispasswd && *cnf->nispasswd=='/') {
				rc = chgnispwent(cnf->nispasswd, a_name->val, pwd);
				if (rc == -1)
					warn("User '%s' not found in NIS passwd", pwd->pw_name);
				else
					warn("NIS passwd update");
				/* NOTE: NIS-only update errors are not fatal */
			}
		}
	}

	/*
	 * Ok, user is created or changed - now edit group file
	 */

	if (mode == M_ADD || getarg(args, 'G') != NULL) {
		int i;
		for (i = 0; cnf->groups[i] != NULL; i++) {
			grp = GETGRNAM(cnf->groups[i]);
			grp = gr_add(grp, pwd->pw_name);
			/*
			 * grp can only be NULL in 2 cases:
			 * - the new member is already a member
			 * - a problem with memory occurs
			 * in both cases we want to skip now.
			 */
			if (grp == NULL)
				continue;
			chggrent(cnf->groups[i], grp);
			free(grp);
		}
	}


	/* go get a current version of pwd */
	pwd = GETPWNAM(a_name->val);
	if (pwd == NULL) {
		/* This will fail when we rename, so special case that */
		if (mode == M_UPDATE && (arg = getarg(args, 'l')) != NULL) {
			a_name->val = arg->val;		/* update new name */
			pwd = GETPWNAM(a_name->val);	/* refetch renamed rec */
		}
	}
	if (pwd == NULL)	/* can't go on without this */
		errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val);

	grp = GETGRGID(pwd->pw_gid);
	pw_log(cnf, mode, W_USER, "%s(%ld):%s(%ld):%s:%s:%s",
	       pwd->pw_name, (long) pwd->pw_uid,
	    grp ? grp->gr_name : "unknown", (long) (grp ? grp->gr_gid : -1),
	       pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell);

	/*
	 * If adding, let's touch and chown the user's mail file. This is not
	 * strictly necessary under BSD with a 0755 maildir but it also
	 * doesn't hurt anything to create the empty mailfile
	 */
	if (mode == M_ADD) {
		if (!PWALTDIR()) {
			sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
			close(open(line, O_RDWR | O_CREAT, 0600));	/* Preserve contents &
									 * mtime */
			chown(line, pwd->pw_uid, pwd->pw_gid);
		}
	}

	/*
	 * Let's create and populate the user's home directory. Note
	 * that this also `works' for editing users if -m is used, but
	 * existing files will *not* be overwritten.
	 */
	if (!PWALTDIR() && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) {
		copymkdir(pwd->pw_dir, cnf->dotdir, cnf->homemode, pwd->pw_uid, pwd->pw_gid);
		pw_log(cnf, mode, W_USER, "%s(%ld) home %s made",
		       pwd->pw_name, (long) pwd->pw_uid, pwd->pw_dir);
	}


	/*
	 * Finally, send mail to the new user as well, if we are asked to
	 */
	if (mode == M_ADD && !PWALTDIR() && cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) {
		FILE           *pfp = popen(_PATH_SENDMAIL " -t", "w");
		
		if (pfp == NULL)
			warn("sendmail");
		else {
			fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name);
			while (fgets(line, sizeof(line), fp) != NULL) {
				/* Do substitutions? */
				fputs(line, pfp);
			}
			pclose(pfp);
			pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent",
			    pwd->pw_name, (long) pwd->pw_uid);
		}
		fclose(fp);
	}

	return EXIT_SUCCESS;
}
示例#30
0
int
main(int argc, char **argv, char **envp)
{
	FILE *config;
	char *line, *cp, *from, *to, *ap;
	const char *progname;
	size_t len, lineno = 0;
	int i;
	struct arglist al;

	/* change progname to mailwrapper so we get sensible error messages */
	progname = getprogname();
	setprogname("mailwrapper");

	if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) {
		openlog("mailwrapper", LOG_PID, LOG_MAIL);
		syslog(LOG_INFO, "can't open %s, using %s as default MTA",
		    _PATH_MAILERCONF, _PATH_DEFAULTMTA);
		closelog();
		execve(_PATH_DEFAULTMTA, argv, envp);
		err(1, "cannot exec %s", _PATH_DEFAULTMTA);
		/*NOTREACHED*/
	}

	initarg(&al);
	addarg(&al, argv[0], 0);

	for (;;) {
		if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) {
			if (feof(config))
				errx(1, "no mapping in %s", _PATH_MAILERCONF);
			err(1, NULL);
		}

#define	WS	" \t\n"
		cp = line;

		cp += strspn(cp, WS);
		if (cp[0] == '\0') {
			/* empty line */
			free(line);
			continue;
		}

		if ((from = strsep(&cp, WS)) == NULL)
			goto parse_error;

		cp += strspn(cp, WS);

		if ((to = strsep(&cp, WS)) == NULL)
			goto parse_error;

		if (strcmp(from, progname) == 0) {
			for (ap = strsep(&cp, WS); ap != NULL;
			    ap = strsep(&cp, WS))
			    if (*ap)
				    addarg(&al, ap, 0);
			break;
		}

		free(line);
	}

	fclose(config);

	for (i = 1; i < argc; i++)
		addarg(&al, argv[i], 0);
	addarg(&al, NULL, 0);

	execve(to, al.argv, envp);
	err(1, "cannot exec %s", to);
	/*NOTREACHED*/
parse_error:
	errx(1, "parse error in %s at line %lu",
	    _PATH_MAILERCONF, (u_long)lineno);
	/*NOTREACHED*/
}