示例#1
0
文件: test.c 项目: zgbkny/ctoolx
static void open_log_files(void)
{
  int fd;
  char str[32];

  if (interactive_mode)
    return;

  /* Open access log */
  if (log_access)
    logbuf_open();

  /* Open and write pid to pid file */
  if ((fd = open(PID_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
    err_sys_quit(errfd, "ERROR: can't open pid file: open");
  sprintf(str, "%d\n", (int)getpid());
  if (write(fd, str, strlen(str)) != strlen(str))
    err_sys_quit(errfd, "ERROR: can't write to pid file: write");
  close(fd);

  /* Open error log file */
  if ((fd = open(ERRORS_FILE, O_CREAT | O_WRONLY | O_APPEND, 0644)) < 0)
    err_sys_quit(errfd, "ERROR: can't open error log file: open");
  errfd = fd;

  err_report(errfd, "INFO: starting the server...");
}
示例#2
0
文件: test.c 项目: zgbkny/ctoolx
static void start_threads(void)
{
  long i, n;

  /* Create access log flushing thread */
  if (log_access && st_thread_create(flush_acclog_buffer, NULL, 0, 0) == NULL)
    err_sys_quit(errfd, "ERROR: process %d (pid %d): can't create"
		 " log flushing thread", my_index, my_pid);

  /* Create connections handling threads */
  for (i = 0; i < sk_count; i++) {
    err_report(errfd, "INFO: process %d (pid %d): starting %d threads"
	       " on %s:%u", my_index, my_pid, max_wait_threads,
	       srv_socket[i].addr, srv_socket[i].port);
    WAIT_THREADS(i) = 0;
    BUSY_THREADS(i) = 0;
    RQST_COUNT(i) = 0;
    for (n = 0; n < max_wait_threads; n++) {
      if (st_thread_create(handle_connections, (void *)i, 0, 0) != NULL)
	WAIT_THREADS(i)++;
      else
	err_sys_report(errfd, "ERROR: process %d (pid %d): can't create"
		       " thread", my_index, my_pid);
    }
    if (WAIT_THREADS(i) == 0)
      exit(1);
  }
}
示例#3
0
/*
 * Function: insert_data
 *
 * Description: This routine inserts the data into the table
 *
 */
void insert_data()
{

  colp *colsptr;
  sword colindex;

  row_count = 0;
  while (row_count < numrows)
  {

    colsptr = cols;
    numinsert = numrows - row_count < MAX_ROWS_PER_INSERT ?
                       numrows - row_count : MAX_ROWS_PER_INSERT;

    for (colindex = 0; colindex < NUMCOLS; colsptr++, colindex++)
    {
       initialize_data(colsptr->c_buf, colsptr->c_size, colsptr->c_rlen,
                       numinsert);
       colsptr->c_curlen = numinsert;
    }

                      /* using offset zero - we want all the rows right away */
    if (oexec(&cda))
    {
        err_report(&cda);
        do_exit(OCI_EXIT_FAILURE);
    }

    printf(" Number of rows processed so far is %d\n", retval);

    row_count += numinsert;
  }

}
示例#4
0
static void parse_arguments( int argc, char *argv[] )
{
    extern char *optarg;
    int opt;
    char* c = NULL;

    while (( opt = getopt( argc, argv, "b:p:l:h" ) ) != EOF )
    {
        switch ( opt )
        {
            case 'b':
                if (( c = strdup( optarg ) ) == NULL )
                    err_sys_quit( s_errfd, "ERROR: strdup" );
                s_serverIP = c;
                break;
            case 'p':
                s_nListenPort = atoi( optarg );
                if ( s_nListenPort < 1024 )
                    err_quit( s_errfd, "ERROR: invalid listening port: %s", optarg );
                break;
            case 'l':
                s_logdir = optarg;
                break;
            case 'h':
            case '?':
                usage( argv[0] );
        }
    }

    if ( s_logdir == NULL )
    {
        err_report( s_errfd, "ERROR: logging directory is required\n" );
        usage( argv[0] );
    }
}
示例#5
0
int	unsetenv_manager(t_manage *man, char *cmd)
{
  int	pos;
  char	**d_cmd;
  char	**d_all;
  int	i;
  int	nb_of_args;
  int	j;

  i = -1;
  j = 1;
  d_all = my_str_to_wordtab(cmd, ' ');
  while (d_all[++i])
    {
      pos = 0;
      if ((nb_of_args = wordtab_count(d_all)) == 1)
	{
	  err_report(3, "NULL");
	  return (-1);
	}
      d_cmd = get_args(cmd);
      if ((pos = my_getenv(man->all_env->my_env, d_cmd[j])) == -1)
	return (-1);
      man->all_env->my_env = d_tab_unset_doc(man->all_env->my_env, pos - 1);
      j = j + 1;
    }
  return (0);
}
示例#6
0
文件: test.c 项目: zgbkny/ctoolx
static void wdog_sighandler(int signo)
{
  int i, err;

  /* Save errno */
  err = errno;
  /* Forward the signal to all children */
  for (i = 0; i < vp_count; i++) {
    if (vp_pids[i] > 0)
      kill(vp_pids[i], signo);
  }
  /*
   * It is safe to do pretty much everything here because process is
   * sleeping in wait() which is async-safe.
   */
  switch (signo) {
  case SIGHUP:
    err_report(errfd, "INFO: watchdog: caught SIGHUP");
    /* Reopen log files - needed for log rotation */
    if (log_access) {
      logbuf_close();
      logbuf_open();
    }
    close(errfd);
    if ((errfd = open(ERRORS_FILE, O_CREAT | O_WRONLY | O_APPEND, 0644)) < 0)
      err_sys_quit(STDERR_FILENO, "ERROR: watchdog: open");
    break;
  case SIGTERM:
    /* Non-graceful termination */
    err_report(errfd, "INFO: watchdog: caught SIGTERM, terminating");
    unlink(PID_FILE);
    exit(0);
  case SIGUSR1:
    err_report(errfd, "INFO: watchdog: caught SIGUSR1");
    break;
  default:
    err_report(errfd, "INFO: watchdog: caught signal %d", signo);
  }
  /* Restore errno */
  errno = err;
}
示例#7
0
文件: clif.c 项目: smx-smx/dsl-n55u
static void err_bad_res (const CLIF_option *optn, char c,
					const char *opt_arg, int n) {
	CLIF_option tmp = *optn;
	char *ss;
	const char *type;

	tmp.arg_name = NULL;

	if (c) {
	    ss = show_short (&tmp);
	    type = "option";
	} else {
	    ss = show_long (&tmp);
	    type = is_keyword (optn) ? "keyword" : "option";
	}

	if (optn->arg_name)
	    err_report ("Cannot handle `%s' %s with arg `%s' (argc %d)",
							ss, type, opt_arg, n);
	else
	    err_report ("Cannot handle `%s' %s (argc %d)", ss, type, n);
}
示例#8
0
int main(int argc, char *argv[])
{
    int fd;     //file desciptor

    fd=open(argv[0],O_RDONLY);

    if(fd == -1)
        err_report("error in opening ");
    else
        printf("You have open a file successfully\r\n");

    exit(0);
}
示例#9
0
文件: test.c 项目: zgbkny/ctoolx
static void change_user(void)
{
  struct passwd *pw;

  if ((pw = getpwnam(username)) == NULL)
    err_quit(errfd, "ERROR: can't find user '%s': getpwnam failed", username);

  if (setgid(pw->pw_gid) < 0)
    err_sys_quit(errfd, "ERROR: can't change group id: setgid");
  if (setuid(pw->pw_uid) < 0)
    err_sys_quit(errfd, "ERROR: can't change user id: setuid");

  err_report(errfd, "INFO: changed process user id to '%s'", username);
}
示例#10
0
文件: exe.c 项目: Docteur-RS/42sh
int	check_cmd_in_list(t_list *list, t_manage *man)
{
  while (list->next != NULL && list->num != -1)
    {
      if ((is_built_ins(list->cmd) == 0) && is_path_cmd(list, man) == 0)
	{
	  err_report(0, list->cmd);
	  return (0);
	}
      if (list->next != NULL && (list->num == 3 || list->num == 5))
	list = list->next;
      if (list->next != NULL)
	list = list->next;
    }
  return (1);
}
示例#11
0
文件: clif.c 项目: smx-smx/dsl-n55u
static void err_bad_excl (const CLIF_option *optn, char c, int n) {
	CLIF_option tmp = *optn;
	char *ss;
	char *excl = show_excl (curr.option_list, 0);
				/*  Note: show_(short|long)() nested!!! */

	tmp.arg_name = NULL;

	if (c)  ss = show_short (&tmp);
	else  ss = show_long (&tmp);

	err_report ("%s `%s' (argc %d): Only one of:\n    %s\n"
		    "may be specified.",
		    (c || !is_keyword (optn)) ? "Option" : "Keyword",
							    ss, n, excl);
}
示例#12
0
文件: clif.c 项目: smx-smx/dsl-n55u
static void err_bad_arg (const CLIF_option *optn, char c, int n) {
	CLIF_option tmp = *optn;
	char ss[80];
	char *s;

	tmp.arg_name = NULL;

	if (c) {
	    s = show_short (&tmp);	/*  always without arg...  */
	    strncpy (ss, s, sizeof (ss));
	    s = show_short (optn);
	} else {
	    s = show_long (&tmp);	/*  always without arg...  */
	    strncpy (ss, s, sizeof (ss));
	    s = show_long (optn);
	}

	err_report ("%s `%s' (argc %d) requires an argument: `%s'",
		    (c || !is_keyword (optn)) ? "Option" : "Keyword", ss, n, s);
}
示例#13
0
文件: test.c 项目: zgbkny/ctoolx
/*
 * Configuration loading function stub.
 */
void load_configs(void)
{
  err_report(errfd, "INFO: process %d (pid %d): configuration loaded",
	     my_index, my_pid);
}
示例#14
0
cchobj cch_alloc(cch c, size_t size, cchobj *owner)
{
	cchobj obj;
	bool wrapped_this_time;

	/* Allow for size of cchobj_str */
	size += sizeof(struct cchobj_str);

	/* 4 byte align */
	size = (size + 3) & ~3;

	if (size > c->size) {
		err_report("cch_alloc: %i > cache size of %i", size, c->size);
		return NULL;
	}

	/* If there is not size bytes after the rover, reset to the cache base */
	wrapped_this_time = false;
	if (!c->rover)
		c->rover = c->base;
	else if (cch_free(c) < size) {
		wrapped_this_time = true;
		c->rover = c->base;
	}

	/* Collect and free objects until the rover block is large enough */
	obj = c->rover;
	if (c->fast) {
		if(!globalGL.glTestFenceNV(c->rover->fence))
			globalGL.glFinishFenceNV(c->rover->fence);
		globalGL.glDeleteFencesNV(1, &(c->rover->fence));
	}
	if (c->rover->owner)
		*(c->rover->owner) = NULL;
	while (obj->size < size) {
		/* Free another object */
		c->rover = c->rover->next;
		if (c->fast) {
			if(!globalGL.glTestFenceNV(c->rover->fence))
				globalGL.glFinishFenceNV(c->rover->fence);
			globalGL.glDeleteFencesNV(1, &(c->rover->fence));
		}
		if (c->rover->owner)
			*(c->rover->owner) = NULL;
		obj->size += c->rover->size;
		obj->next = c->rover->next;
	}

	/* Create a fragment out of any leftovers */
	if (obj->size - size > 63) {
		c->rover = (cchobj)(((unsigned char*)obj) + size);
		c->rover->size = obj->size - size;
		c->rover->next = obj->next;
		c->rover->owner = NULL;
		obj->next = c->rover;
		obj->size = size;
	}
	else
		c->rover = obj->next;

	*owner = obj;
	obj->owner = owner;
	if (c->fast)
		globalGL.glGenFencesNV(1, &(obj->fence));

	if (c->wrapped) {
		if (wrapped_this_time || (c->rover >= c->initRover))
			c->thrashed = true;
	}
	else if (wrapped_this_time)
		c->wrapped = true;

	if (c->fast)
		obj->data = 
			(((unsigned char*)(obj + 1)) - (unsigned char*)c->base) + c->fastBase;
	else
		obj->data = (unsigned char*)(obj + 1);

	return obj;
}
示例#15
0
/*
 * Function: setup
 *
 * Description: This routine does the necessary setup to execute the SQL
 *              statement. Specifically, it does the open, parse, bind and
 *              define phases as needed.
 *
 */
void setup()
{

  colp *colsptr;                                        /* temporary pointer */
  sword colindex;

  if (oopen(&cda, &lda, (text *) 0, -1, -1, (text *) 0, -1))         /* open */
  {
    err_report(&cda);
    do_exit(OCI_EXIT_FAILURE);
  }

  if (oparse(&cda, sqlstmt, (sb4) -1, DEFER_PARSE,                  /* parse */
               (ub4) VERSION_7))
  {
    err_report(&cda);
    do_exit(OCI_EXIT_FAILURE);
  }

                                                          /* bind the scalar */

  if (obndra(&cda, (text *)":numins", -1,
             (ub1 *)&numinsert, (sword)sizeof(numinsert),
             SQLT_INT, -1, (sb2 *) 0, (ub2 *)0, (ub2 *)0,
             (ub4)0, (ub4 *)0, (text *)0, -1, -1))                   /* bind */
  {
    err_report(&cda);
    do_exit(OCI_EXIT_FAILURE);
  }

  if (obndra(&cda, (text *)":retval", -1,
             (ub1 *)&retval, (sword)sizeof(retval),
             SQLT_INT, -1, (sb2 *) 0, (ub2 *)0, (ub2 *)0,
             (ub4)0, (ub4 *)0, (text *)0, -1, -1))                   /* bind */
  {
    err_report(&cda);
    do_exit(OCI_EXIT_FAILURE);
  }

  cols = malloc_col(NUMCOLS);
  colsptr = cols;
  for (colindex = 0; colindex < NUMCOLS; colindex++, colsptr++)
  {

    colsptr->c_size  = coltable[colindex].size;
    colsptr->c_type  = coltable[colindex].type;
    colsptr->c_indp  = (sb2*)malloc((size_t)(MAX_ROWS_PER_INSERT*sizeof(sb2)));
    memset((dvoid *)colsptr->c_indp, 0, MAX_ROWS_PER_INSERT * sizeof(sb2));
    colsptr->c_rlen  = (ub2*)malloc((size_t)(MAX_ROWS_PER_INSERT*sizeof(ub2)));
    memset((dvoid *)colsptr->c_rlen, 0, MAX_ROWS_PER_INSERT * sizeof(ub2));
    colsptr->c_rcode = (ub2*)malloc((size_t)(MAX_ROWS_PER_INSERT*sizeof(ub2)));
    memset((dvoid *)colsptr->c_rcode, 0, MAX_ROWS_PER_INSERT * sizeof(ub2));
    colsptr->c_buf   =
                  (ub1 *)malloc((size_t)(MAX_ROWS_PER_INSERT*colsptr->c_size));
    memset((dvoid *)colsptr->c_buf, 0, MAX_ROWS_PER_INSERT * colsptr->c_size);
    colsptr->c_curlen = 0;

    switch (colindex) {
    case(0) :

/* GOTCHA!!! - need to pass in zeroes for mal and cal parameters when
   running a regular insert. Set it to non-zero when using plsql */
        if (obndra(&cda, (text *)":col1", -1,
                   colsptr->c_buf, colsptr->c_size,
                   (sword)colsptr->c_type, (sword) -1,
                   (sb2 *)colsptr->c_indp, colsptr->c_rlen, colsptr->c_rcode,
                   (ub4)MAX_ROWS_PER_INSERT, (ub4 *)&(colsptr->c_curlen),
                   (text *)0, -1, -1))
        {
          err_report(&cda);
          do_exit(OCI_EXIT_FAILURE);
        }
        break;
    }

  }

}
示例#16
0
文件: test.c 项目: zgbkny/ctoolx
static void start_processes(void)
{
  int i, status;
  pid_t pid;
  sigset_t mask, omask;

  if (interactive_mode) {
    my_index = 0;
    my_pid = getpid();
    return;
  }

  for (i = 0; i < vp_count; i++) {
    if ((pid = fork()) < 0) {
      err_sys_report(errfd, "ERROR: can't create process: fork");
      if (i == 0)
	exit(1);
      err_report(errfd, "WARN: started only %d processes out of %d", i,
		 vp_count);
      vp_count = i;
      break;
    }
    if (pid == 0) {
      my_index = i;
      my_pid = getpid();
      /* Child returns to continue in main() */
      return;
    }
    vp_pids[i] = pid;
  }

  /*
   * Parent process becomes a "watchdog" and never returns to main().
   */

  /* Install signal handlers */
  Signal(SIGTERM, wdog_sighandler);  /* terminate */
  Signal(SIGHUP,  wdog_sighandler);  /* restart   */
  Signal(SIGUSR1, wdog_sighandler);  /* dump info */

  /* Now go to sleep waiting for a child termination or a signal */
  for ( ; ; ) {
    if ((pid = wait(&status)) < 0) {
      if (errno == EINTR)
	continue;
      err_sys_quit(errfd, "ERROR: watchdog: wait");
    }
    /* Find index of the exited child */
    for (i = 0; i < vp_count; i++) {
      if (vp_pids[i] == pid)
	break;
    }

    /* Block signals while printing and forking */
    sigemptyset(&mask);
    sigaddset(&mask, SIGTERM);
    sigaddset(&mask, SIGHUP);
    sigaddset(&mask, SIGUSR1);
    sigprocmask(SIG_BLOCK, &mask, &omask);

    if (WIFEXITED(status))
      err_report(errfd, "WARN: watchdog: process %d (pid %d) exited"
		 " with status %d", i, pid, WEXITSTATUS(status));
    else if (WIFSIGNALED(status))
      err_report(errfd, "WARN: watchdog: process %d (pid %d) terminated"
		 " by signal %d", i, pid, WTERMSIG(status));
    else if (WIFSTOPPED(status))
      err_report(errfd, "WARN: watchdog: process %d (pid %d) stopped"
		 " by signal %d", i, pid, WSTOPSIG(status));
    else
      err_report(errfd, "WARN: watchdog: process %d (pid %d) terminated:"
		 " unknown termination reason", i, pid);

    /* Fork another VP */
    if ((pid = fork()) < 0) {
      err_sys_report(errfd, "ERROR: watchdog: can't create process: fork");
    } else if (pid == 0) {
      my_index = i;
      my_pid = getpid();
      /* Child returns to continue in main() */
      return;
    }
    vp_pids[i] = pid;

    /* Restore the signal mask */
    sigprocmask(SIG_SETMASK, &omask, NULL);
  }
}
bool
str2userinfo (sfsauth_userinfo *ui, str s)
{
  str name;
  vec<str> uv;
  if (split (&uv, colon, s, 12, true) != 11)
    return false;
  str2wstr (uv[7]);
  str2wstr (uv[8]);
  str fields[13] = { "name", "uid", "version", "gid", "owner",
		     "pubkey", "privs", "srp", "privkey", 
		     "srvprivkey", // "refresh", "timeout",
		     "audit" };

  if (!namerx.match (uv[0])) {
    err_report ("<null>", 1, fields[0], uv[0]);
    return false;
  }
  name = uv[0];

  for (int i = 1; i < 4; i++) {
    if (!decrx.match (uv[i])) {
      err_report (name, i+1, fields[i], uv[i]);
      return false;
    }
  }
  if (uv[4].len () && !namerx.match (uv[4])) {
    err_report (name, 5, fields[4], uv[4]);
    return false;
  }
  for (int i = 6; i < 10; i++) {
    if (badcharrx.search (uv[i])) {
      err_report (name, i+1, fields[i], uv[i]);
      return false;
    }
  }
#if 0
  for (int i = 10; i < 12; i++) {
    if (!decrx.match (uv[i])) {
      err_report (name, i+1, fields[i], uv[i]);
      return false;
    }
  }
#endif

  str privkey = dearmor64 (uv[8]);
  if (!privkey) {
    err_report (name, 9, fields[8], "could not dearmor64");
    return false;
  }
  str2wstr (privkey);
  ui->privkey.setsize (privkey.len ());
  memcpy (ui->privkey.base (), privkey, ui->privkey.size ());

  ui->name = uv[0];
  if (!convertint (uv[1], &ui->id)
      || !convertint (uv[2], &ui->vers)
      || !convertint (uv[3], &ui->gid)
      // || !convertint (uv[10], &ui->refresh)
      // || !convertint (uv[11], &ui->timeout)
      )
    return false;
  if (uv[4].len ())
    *ui->owner.alloc () = uv[4];
  else
    ui->owner.clear ();

  ptr<sfspub> pk = sfscrypt.alloc (uv[5]);
  if (!pk)
    return false;

  if (!pk->export_pubkey (&ui->pubkey)) {
    warn << "Cannot load keypair for " << uv[0] << "\n";
    return false;
  }

  ui->privs = uv[6];
  ui->pwauth = uv[7];
  if (uv[9] && uv[9].len ()) {
    if (!sfs_2schnorr_priv::parse_keyhalf (&ui->srvprivkey, uv[9])) {
      warn << "Cannot load server keyhalf for " << uv[0] << "\n";
      return false;
    }
  } else {
    ui->srvprivkey.set_type (SFSAUTH_KEYHALF_NONE);
  }
  // ui->audit = uv[12];
  ui->audit = uv[10];
  return true;
}
示例#18
0
文件: test.c 项目: zgbkny/ctoolx
static void parse_arguments(int argc, char *argv[])
{
  extern char *optarg;
  int opt;
  char *c;

  while ((opt = getopt(argc, argv, "b:p:l:t:u:q:aiSh")) != EOF) {
    switch (opt) {
    case 'b':
      if (sk_count >= MAX_BIND_ADDRS)
	err_quit(errfd, "ERROR: max number of bind addresses (%d) exceeded",
		 MAX_BIND_ADDRS);
      if ((c = strdup(optarg)) == NULL)
	err_sys_quit(errfd, "ERROR: strdup");
      srv_socket[sk_count++].addr = c;
      break;
    case 'p':
      vp_count = atoi(optarg);
      if (vp_count < 1)
	err_quit(errfd, "ERROR: invalid number of processes: %s", optarg);
      break;
    case 'l':
      logdir = optarg;
      break;
    case 't':
      max_wait_threads = (int) strtol(optarg, &c, 10);
      if (*c++ == ':')
	max_threads = atoi(c);
      if (max_wait_threads < 0 || max_threads < 0)
	err_quit(errfd, "ERROR: invalid number of threads: %s", optarg);
      break;
    case 'u':
      username = optarg;
      break;
    case 'q':
      listenq_size = atoi(optarg);
      if (listenq_size < 1)
	err_quit(errfd, "ERROR: invalid listen queue size: %s", optarg);
      break;
    case 'a':
      log_access = 1;
      break;
    case 'i':
      interactive_mode = 1;
      break;
    case 'S':
      /*
       * Serialization decision is tricky on some platforms. For example,
       * Solaris 2.6 and above has kernel sockets implementation, so supposedly
       * there is no need for serialization. The ST library may be compiled
       * on one OS version, but used on another, so the need for serialization
       * should be determined at run time by the application. Since it's just
       * an example, the serialization decision is left up to user.
       * Only on platforms where the serialization is never needed on any OS
       * version st_netfd_serialize_accept() is a no-op.
       */
      serialize_accept = 1;
      break;
    case 'h':
    case '?':
      usage(argv[0]);
    }
  }

  if (logdir == NULL && !interactive_mode) {
    err_report(errfd, "ERROR: logging directory is required\n");
    usage(argv[0]);
  }

  if (getuid() == 0 && username == NULL)
    err_report(errfd, "WARNING: running as super-user!");

  if (vp_count == 0 && (vp_count = cpu_count()) < 1)
    vp_count = 1;

  if (sk_count == 0) {
    sk_count = 1;
    srv_socket[0].addr = "0.0.0.0";
  }
}
示例#19
0
文件: clif.c 项目: smx-smx/dsl-n55u
int CLIF_parse_cmdline (int argc, char *argv[],
			CLIF_option *option_list,
			CLIF_argument *argument_list,
			unsigned int parse_flags) {
	int i, j;
	CLIF_option *optn;
	CLIF_argument *argm;
	int num_args = 0;
	int num_argm = 0, strict_beg = 0, strict_end = 0;
	_CLIF_index arg_n[MAX_ARGC_NUMBER];
	unsigned int dirty_flags = 0;
	int dirty_plus = 0;
	int exclusive_cnt = 0;
	int posix = getenv ("POSIXLY_CORRECT") != NULL ||
					    (parse_flags & CLIF_POSIX);

	curr.argc = argc;
	curr.argv = argv;
	curr.option_list = option_list;
	curr.argument_list = argument_list;
	curr.parse_flags = parse_flags;

	if (argc <= 1 && (parse_flags & CLIF_HELP_EMPTY)) {
		CLIF_current_help ();
		exit (0);
	}

	/*  Scan argument_list for check and some info.  */
	if (argument_list) {
	    enum stages { STRICT_BEG, OPTIONAL, STRICT_END };
	    int stage = STRICT_BEG;

	    for (argm = argument_list; argm->name; argm++) {
		
		if (argm->flags & CLIF_STRICT) {

		    if (stage == STRICT_BEG)  strict_beg++;
		    else if (stage == OPTIONAL) {
			stage = STRICT_END;
			strict_end++;
		    }
		    else if (stage == STRICT_END)
			    strict_end++;
		} else {
		    if (stage == STRICT_BEG)  stage = OPTIONAL;
		    else if (stage == STRICT_END) {
			err_report ("Incorrect argument list set in program "
				    "source: more than one optional area.");
			return -1;
		    }
		}

		num_argm++;
	    }
	}
	
	/*  Scan option_list for some info.  */
	if (option_list) {

	    dirty_flags = parse_flags;

	    for (optn = option_list;
		    optn->short_opt || optn->long_opt;
			optn++
	    ) {
		dirty_flags |= optn->flags;
		if (optn->function_plus)  dirty_plus = 1;
	    }
	}

	if (dirty_flags & CLIF_EXCL)
		exclusive_cnt = 1;	/*  only one is allowed...  */


	/*  Go !   Store arguments, parse options.  */

	for (i = 1; i < argc; i++) {
	    char *arg = argv[i];
	    char *opt_arg = NULL;
	    char sym = '-';

	    if (!option_list)
		    goto  handle_arg;

	    if (*arg == '+' && dirty_plus)
		    sym = '+';

	    if (*arg != sym) {	/*  argument or keyword   */

		if (dirty_flags & CLIF_MAY_KEYWORD) {
		    optn = find_long (arg, &opt_arg, CLIF_MAY_KEYWORD, 0);
		    if (optn)  goto long_found;
		}

		if (num_args == 0 && (parse_flags & CLIF_FIRST_GROUP)) {
		    /*  ugly...  */
		    parse_flags &= ~CLIF_FIRST_GROUP;
		    dirty_flags &= ~CLIF_FIRST_GROUP;	/*  to be correct   */

		    goto  handle_short;
		}

		/*  else it is an argument   */
		goto  handle_arg;

	    }
	    else if (*++arg == sym) {	/*  `--' - long option   */
		arg++;

		if (*arg == sym ||	/*  `---' - let it be not option... */
		    (parse_flags & (_CLIF_STRICT_KEYWORD|_CLIF_STRICT_ONEDASH)) 
		) {
		    arg -= 2;
		    goto  handle_arg;	/*  not option anyway  */
		}
	
		optn = find_long (arg, &opt_arg, 0,
				_CLIF_STRICT_KEYWORD | _CLIF_STRICT_ONEDASH);
		if (optn)  goto long_found;
	
		/*  XXX: May be allow only for `--', not `++' too...  */
		if (!*arg && sym == '-') {  /*  `--' and no empty longoption */
		    option_list = NULL;	    /*  POSIX way...  */
		    continue;
		}
	
		/*  XXX: or treat as an argument sometimes???  */
		err_bad_opt (argv[i], 0, i);
		return -1;
	    }
	    else {	/*  short option, or several short options...  */

		if (dirty_flags & CLIF_MAY_ONEDASH) {
		    optn = find_long (arg, &opt_arg, CLIF_MAY_ONEDASH, 0);
		    if (optn)  goto long_found;
		}
    
		if (!*arg) {	/*  POSIX say: only "stdout specification"... */
		    arg--;
		    goto handle_arg;
		}
    
		goto  handle_short;
	    }


    long_found:	
	    if (check_sym (optn, sym) < 0) {	/*  Oops...  */
		err_bad_opt (argv[i], 0, i);
		return -1;
	    }

	    if (optn->flags & CLIF_EXCL) {
		if (!exclusive_cnt) {
		    err_bad_excl (optn, 0, i);
		    return -1;
		}
		exclusive_cnt--;
	    }
		
	    if (optn->arg_name && !opt_arg) {
		unsigned int flags = optn->flags | parse_flags;

		if (++i >= argc ||
		    !(flags & CLIF_MAY_NOEQUAL)
		) {	/*  missing opt arg   */
		    i--;

		    if (!(flags & CLIF_OPTARG)) {
			err_bad_arg (optn, 0, i);
			return -1;
		    }

		    opt_arg = NULL;
		} else
		    opt_arg = argv[i];
		   
	    }


	    if (call_function (optn, opt_arg, sym) < 0) {
		err_bad_res (optn, 0, opt_arg, i);
		return -1;
	    }

	    if (optn->flags & CLIF_EXIT)
		    exit (0);

	    continue;


    handle_arg:
	    if (argument_list) {
		if (i < MAX_ARGC_NUMBER)    /*  XXX: ugly, better report   */
			arg_n[num_args++] = i;
	    } else {
		err_report ("`%s' (argc %d): arguments are not allowed",
								 argv[i], i);
		return -1;
	    }

	    /*  POSIX say: No more options after args...  */
	    if (posix)  option_list = NULL;	/*  geniously...  */
	
	    continue;


    handle_short:

	    opt_arg = NULL;

	    do {

		for (optn = option_list;
			optn->short_opt || optn->long_opt;
			    optn++
		) {
		    if (optn->short_opt && optn->short_opt[0] == *arg)
			    break;
		}
		if (!optn->short_opt ||
		    check_sym (optn, sym) < 0
		) {
		    err_bad_opt (argv[i], *arg, i);
		    return -1;
		}

		if (optn->flags & CLIF_EXCL) {
		    if (!exclusive_cnt) {
			err_bad_excl (optn, *arg, i);
			return -1;
		    }
		    exclusive_cnt--;
		}


		if (optn->arg_name) {
		    unsigned int flags = parse_flags | optn->flags;

		    if (arg[1] == '\0') {	/*  a last one   */

			/*  POSIX say: an option with arg cannot be grouped. */
			if (posix && arg != argv[i] && arg[-1] != sym) {
				err_bad_arg (optn, *arg, i);	/*  good way? */
				return -1;
			}

			if (++i >= argc ||
			    (flags & _CLIF_STRICT_JOIN_ARG)
			) {
			    i--;

			    if (!(flags & CLIF_OPTARG)) {
				err_bad_arg (optn, *arg, i);
				return -1;
			    }

			    opt_arg = NULL;
			} else
			    opt_arg = argv[i];
		    }
		    else if ((arg == argv[i] || arg[-1] == sym) &&	
			     (flags & CLIF_MAY_JOIN_ARG)
		    ) {
			opt_arg = ++arg;
		    }
		    else {	/*  inside a group...  */
			if (!(flags & CLIF_OPTARG) ||
			    (flags & CLIF_MAY_JOIN_ARG)
			) {
			    err_bad_arg (optn, *arg, i);
			    return -1;
			}

			opt_arg = NULL;
		    }
		}

		if (call_function (optn, opt_arg, sym) < 0) {
		    err_bad_res (optn, optn->short_opt[0], opt_arg, i);
		    return -1;
		}

		if (optn->flags & CLIF_EXIT)
			exit (0);

	    } while (!opt_arg && *++arg);

	}	/*  for ( ...  )   */

	if ((parse_flags & CLIF_STRICT_EXCL) && exclusive_cnt != 0) {
		err_report ("One of these must be specified:\n    %s\n",
						    show_excl (option_list, 0));
		return -1;
	}


	/*  Now, after *ALL* options, handle arguments, if any.  */

	if (num_args < strict_beg + strict_end) {
	    /*  Missing some needed arguments.  */

	    if (num_args < strict_beg)  argm = argument_list + num_args;
	    else
		argm = argument_list +
			    ((num_args - strict_beg) + (num_argm - strict_end));

	    if (num_args == strict_beg + strict_end - 1)
		err_report ("Specify \"%s\" missing argument.", argm->name);
	    else
		err_report ("Specify \"%s\" and other missing arguments.",
								    argm->name);
	    return -1;
	}

	if (num_args > 0) {
	    _CLIF_index argm_index[MAX_ARGC_NUMBER];

	    /*  assing argm (by index) for each arg...  */
		    
	    for (i = 0, j = 0; i < strict_beg; i++, j++)
		    argm_index[i] = j;
	    for (i = num_args - strict_end, j = num_argm - strict_end;
			i < num_args; i++, j++
	    )  argm_index[i] = j;
	    for (i = strict_beg, j = strict_beg;
		    i < num_args - strict_end && j < num_argm - strict_end;
			i++
	    ) {
		argm_index[i] = j;
		if (!(argument_list[j].flags & CLIF_MORE))
			j++;
	    }

	    if (i < num_args - strict_end) {	/*  there are extra args...  */
		err_report ("Extra arg `%s' (position %d, argc %d)",
				    argv[arg_n[i]], i + 1, arg_n[i]);
		return -1;
	    }

	    if (j < num_argm - strict_end &&	
		!(argument_list[j].flags & CLIF_MORE) &&
		/*  ...i.e, there are some missing optional args...  */
		(argument_list[j].flags & CLIF_ACC_PREV)
	    ) {
		if (j == 0)
		    err_report ("Incorrect argument list set: first arg "
				"cannot be `accompanied with previous'.");
		else
		    err_report ("Arg \"%s\" must be specified because "
				"\"%s\" `%s' is used.", argument_list[j].name,
				argument_list[j - 1].name, argv[arg_n[i - 1]]);
		return -1;
	    }
		
	    if (argm_index[--i] == j &&
		    /*  above is true only after OPTIONAL area scan
		       and when `j' is stopped on CLIF_MORE  */
		++j < num_argm - strict_end
		    /*  i.e: there is a *last* one (after CLIF_MORE)
			in the OPTIONAL area  */
	    )  argm_index[i] = j;	/*  *last* is better than *more*   */
		    

	    /*  ...and work now   */

	    for (i = 0; i < num_args; i++) {
		argm = argument_list + argm_index[i];

		if (argm->function &&
		    argm->function (argm, argv[arg_n[i]], i) < 0
		) {
		    err_report ("Cannot handle \"%s\" cmdline arg `%s' "
				"on position %d (argc %d)",
				argm->name, argv[arg_n[i]], i + 1, arg_n[i]);
		    return -1;
		}
	    }

	    /*  That`s all.  */
	}

	return 0;
}