Exemplo n.º 1
0
bool TestReadlist::process ()
{
    TestDirWithTextFiles_facet facet (MIN_STRINGS, MAX_STRINGS, FILES_NO, o_);
    std::string fname = facet.dirname ();
    fname += path_separator ();
    fname += "*.txt";
    StrVec names;
    expand_wildcards (fname.c_str (), names);
    StrVec ll = read_lists (names);
    return true;
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
    bool interative_mode = argc > 1 ? false : true;
    
    std::ifstream ifs;
    if(! interative_mode) {                             // paso 7
        ifs.open(argv[1]);
        std::cin.rdbuf(ifs.rdbuf());
    }
    
    while(! std::cin.eof()) {
        
        if(interative_mode) {
            std::cout << "$> ";
        }
        
        std::string line;
        std::getline(std::cin, line);
        
        if (line.empty() || line[0] == '#') {           // paso 4
            continue;
        }
            
        auto words = split(line);                       // paso 1
        words = expand_wildcards(words);                // paso 8

        size_t pos = words[0].find_first_of('=');         
        if (pos != std::string::npos) {                 // paso 6
          auto name = words[0].substr(0, pos);
          auto value = words[0].substr(pos + 1);
          // con putenv() nos ahorraríamos dividir words[0] pero al volver se queda
          // con un puntero a la cadena para usarlo internamente.
          //  => la cadena words[0] no se puede liberar
          //  => habría que reservar un buffer dinámicamente y copiar words[0] en él.
          setenv(name.c_str(), value.c_str(), 1/* overwrite */);
        }
        else if (words[0] == "exit") {                  // paso 2
            break;
        }
        else if (words[0] == "echo") {                  // paso 3
            echo(words);
        }
        else if (words[0] == "cd") {                    // paso 5
            chdir(words);
        }
        else {
            run(words);                                 // paso 4
        }
    }
    
    return 0;
}
Exemplo n.º 3
0
bool TestFileUtils :: process ()
{
    std::string fname = fixture_.dirname ();
    fname += path_separator ();
    fname += "*.txt";
    StrVec sv;
    expand_wildcards (fname.c_str (), sv);
    StrVec::iterator itr = sv.begin ();
    for (; itr != sv.end (); itr ++)
    {
        o_ << (*itr).c_str () << std::endl;
    }
    if (!sv.size ())
    {
        o_ << "No files to test reader" << std::endl;
        return false;
    }

    LineReader lr (sv.front ().c_str ());
    char* ln;
    int no = 0;
    int slen = 0;
    time_t st = time (NULL);
    while ((ln = lr.nextLine ()))
    {
        ++ no;
        slen += strlen (ln);
        //if (strlen (ln) > 100) o_ << ln;
        if (no % 100000 == 0)
        {
            int td = time (NULL) - st;
            double rd = double (slen) / (1024*1024);
            o_ << "\rline " << no << ", " << rd << " Mb, average speed " << rd / (td?td:1) << " Mb/s    " << std::flush;
        }
    }
    time_t et = time (NULL);
    lr.close ();
    return true;
}
Exemplo n.º 4
0
/*
 * Find a file in a search context.
 * The search context was created with vim_findfile_init() above.
 * Return a pointer to an allocated file name or NULL if nothing found.
 * To get all matching files call this function until you get NULL.
 *
 * If the passed search_context is NULL, NULL is returned.
 *
 * The search algorithm is depth first. To change this replace the
 * stack with a list (don't forget to leave partly searched directories on the
 * top of the list).
 */
char_u *vim_findfile(void *search_ctx_arg)
{
  char_u      *file_path;
  char_u      *rest_of_wildcards;
  char_u      *path_end = NULL;
  ff_stack_T  *stackp;
  int len;
  int i;
  char_u      *p;
  char_u      *suf;
  ff_search_ctx_T *search_ctx;

  if (search_ctx_arg == NULL)
    return NULL;

  search_ctx = (ff_search_ctx_T *)search_ctx_arg;

  /*
   * filepath is used as buffer for various actions and as the storage to
   * return a found filename.
   */
  file_path = xmalloc(MAXPATHL);

  /* store the end of the start dir -- needed for upward search */
  if (search_ctx->ffsc_start_dir != NULL)
    path_end = &search_ctx->ffsc_start_dir[
      STRLEN(search_ctx->ffsc_start_dir)];

  /* upward search loop */
  for (;; ) {
    /* downward search loop */
    for (;; ) {
      /* check if user user wants to stop the search*/
      ui_breakcheck();
      if (got_int)
        break;

      /* get directory to work on from stack */
      stackp = ff_pop(search_ctx);
      if (stackp == NULL)
        break;

      /*
       * TODO: decide if we leave this test in
       *
       * GOOD: don't search a directory(-tree) twice.
       * BAD:  - check linked list for every new directory entered.
       *       - check for double files also done below
       *
       * Here we check if we already searched this directory.
       * We already searched a directory if:
       * 1) The directory is the same.
       * 2) We would use the same wildcard string.
       *
       * Good if you have links on same directory via several ways
       *  or you have selfreferences in directories (e.g. SuSE Linux 6.3:
       *  /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
       *
       * This check is only needed for directories we work on for the
       * first time (hence stackp->ff_filearray == NULL)
       */
      if (stackp->ffs_filearray == NULL
          && ff_check_visited(&search_ctx->ffsc_dir_visited_list
              ->ffvl_visited_list,
              stackp->ffs_fix_path
              , stackp->ffs_wc_path
              ) == FAIL) {
#ifdef FF_VERBOSE
        if (p_verbose >= 5) {
          verbose_enter_scroll();
          smsg((char_u *)"Already Searched: %s (%s)",
              stackp->ffs_fix_path, stackp->ffs_wc_path);
          /* don't overwrite this either */
          msg_puts((char_u *)"\n");
          verbose_leave_scroll();
        }
#endif
        ff_free_stack_element(stackp);
        continue;
      }
#ifdef FF_VERBOSE
      else if (p_verbose >= 5) {
        verbose_enter_scroll();
        smsg((char_u *)"Searching: %s (%s)",
            stackp->ffs_fix_path, stackp->ffs_wc_path);
        /* don't overwrite this either */
        msg_puts((char_u *)"\n");
        verbose_leave_scroll();
      }
#endif

      /* check depth */
      if (stackp->ffs_level <= 0) {
        ff_free_stack_element(stackp);
        continue;
      }

      file_path[0] = NUL;

      /*
       * If no filearray till now expand wildcards
       * The function expand_wildcards() can handle an array of paths
       * and all possible expands are returned in one array. We use this
       * to handle the expansion of '**' into an empty string.
       */
      if (stackp->ffs_filearray == NULL) {
        char_u *dirptrs[2];

        /* we use filepath to build the path expand_wildcards() should
         * expand.
         */
        dirptrs[0] = file_path;
        dirptrs[1] = NULL;

        /* if we have a start dir copy it in */
        if (!vim_isAbsName(stackp->ffs_fix_path)
            && search_ctx->ffsc_start_dir) {
          STRCPY(file_path, search_ctx->ffsc_start_dir);
          add_pathsep(file_path);
        }

        /* append the fix part of the search path */
        STRCAT(file_path, stackp->ffs_fix_path);
        add_pathsep(file_path);

        rest_of_wildcards = stackp->ffs_wc_path;
        if (*rest_of_wildcards != NUL) {
          len = (int)STRLEN(file_path);
          if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
            /* pointer to the restrict byte
             * The restrict byte is not a character!
             */
            p = rest_of_wildcards + 2;

            if (*p > 0) {
              (*p)--;
              file_path[len++] = '*';
            }

            if (*p == 0) {
              /* remove '**<numb> from wildcards */
              STRMOVE(rest_of_wildcards, rest_of_wildcards + 3);
            } else
              rest_of_wildcards += 3;

            if (stackp->ffs_star_star_empty == 0) {
              /* if not done before, expand '**' to empty */
              stackp->ffs_star_star_empty = 1;
              dirptrs[1] = stackp->ffs_fix_path;
            }
          }

          /*
           * Here we copy until the next path separator or the end of
           * the path. If we stop at a path separator, there is
           * still something else left. This is handled below by
           * pushing every directory returned from expand_wildcards()
           * on the stack again for further search.
           */
          while (*rest_of_wildcards
                 && !vim_ispathsep(*rest_of_wildcards))
            file_path[len++] = *rest_of_wildcards++;

          file_path[len] = NUL;
          if (vim_ispathsep(*rest_of_wildcards))
            rest_of_wildcards++;
        }

        /*
         * Expand wildcards like "*" and "$VAR".
         * If the path is a URL don't try this.
         */
        if (path_with_url(dirptrs[0])) {
          stackp->ffs_filearray = (char_u **)xmalloc(sizeof(char *));
          stackp->ffs_filearray[0] = vim_strsave(dirptrs[0]);
          stackp->ffs_filearray_size = 1;
        } else
          /* Add EW_NOTWILD because the expanded path may contain
           * wildcard characters that are to be taken literally.
           * This is a bit of a hack. */
          expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
              &stackp->ffs_filearray_size,
              &stackp->ffs_filearray,
              EW_DIR|EW_ADDSLASH|EW_SILENT|EW_NOTWILD);

        stackp->ffs_filearray_cur = 0;
        stackp->ffs_stage = 0;
      } else
        rest_of_wildcards = &stackp->ffs_wc_path[
          STRLEN(stackp->ffs_wc_path)];

      if (stackp->ffs_stage == 0) {
        /* this is the first time we work on this directory */
        if (*rest_of_wildcards == NUL) {
          /*
           * We don't have further wildcards to expand, so we have to
           * check for the final file now.
           */
          for (i = stackp->ffs_filearray_cur;
               i < stackp->ffs_filearray_size; ++i) {
            if (!path_with_url(stackp->ffs_filearray[i])
                && !os_isdir(stackp->ffs_filearray[i]))
              continue;                 /* not a directory */

            /* prepare the filename to be checked for existence
             * below */
            STRCPY(file_path, stackp->ffs_filearray[i]);
            add_pathsep(file_path);
            STRCAT(file_path, search_ctx->ffsc_file_to_search);

            /*
             * Try without extra suffix and then with suffixes
             * from 'suffixesadd'.
             */
            len = (int)STRLEN(file_path);
            if (search_ctx->ffsc_tagfile)
              suf = (char_u *)"";
            else
              suf = curbuf->b_p_sua;
            for (;; ) {
              /* if file exists and we didn't already find it */
              if ((path_with_url(file_path)
                   || (os_file_exists(file_path)
                       && (search_ctx->ffsc_find_what
                           == FINDFILE_BOTH
                           || ((search_ctx->ffsc_find_what
                                == FINDFILE_DIR)
                               == os_isdir(file_path)))))
#ifndef FF_VERBOSE
                  && (ff_check_visited(
                          &search_ctx->ffsc_visited_list->ffvl_visited_list,
                          file_path
                          , (char_u *)""
                          ) == OK)
#endif
                  ) {
#ifdef FF_VERBOSE
                if (ff_check_visited(
                        &search_ctx->ffsc_visited_list->ffvl_visited_list,
                        file_path
                        , (char_u *)""
                        ) == FAIL) {
                  if (p_verbose >= 5) {
                    verbose_enter_scroll();
                    smsg((char_u *)"Already: %s",
                        file_path);
                    /* don't overwrite this either */
                    msg_puts((char_u *)"\n");
                    verbose_leave_scroll();
                  }
                  continue;
                }
#endif

                /* push dir to examine rest of subdirs later */
                stackp->ffs_filearray_cur = i + 1;
                ff_push(search_ctx, stackp);

                if (!path_with_url(file_path))
                  simplify_filename(file_path);
                if (os_dirname(ff_expand_buffer, MAXPATHL)
                    == OK) {
                  p = path_shorten_fname(file_path,
                      ff_expand_buffer);
                  if (p != NULL)
                    STRMOVE(file_path, p);
                }
#ifdef FF_VERBOSE
                if (p_verbose >= 5) {
                  verbose_enter_scroll();
                  smsg((char_u *)"HIT: %s", file_path);
                  /* don't overwrite this either */
                  msg_puts((char_u *)"\n");
                  verbose_leave_scroll();
                }
#endif
                return file_path;
              }

              /* Not found or found already, try next suffix. */
              if (*suf == NUL)
                break;
              copy_option_part(&suf, file_path + len,
                  MAXPATHL - len, ",");
            }
          }
        } else {
          /*
           * still wildcards left, push the directories for further
           * search
           */
          for (i = stackp->ffs_filearray_cur;
               i < stackp->ffs_filearray_size; ++i) {
            if (!os_isdir(stackp->ffs_filearray[i]))
              continue;                 /* not a directory */

            ff_push(search_ctx,
                ff_create_stack_element(
                    stackp->ffs_filearray[i],
                    rest_of_wildcards,
                    stackp->ffs_level - 1, 0));
          }
        }
        stackp->ffs_filearray_cur = 0;
        stackp->ffs_stage = 1;
      }

      /*
       * if wildcards contains '**' we have to descent till we reach the
       * leaves of the directory tree.
       */
      if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0) {
        for (i = stackp->ffs_filearray_cur;
             i < stackp->ffs_filearray_size; ++i) {
          if (fnamecmp(stackp->ffs_filearray[i],
                  stackp->ffs_fix_path) == 0)
            continue;             /* don't repush same directory */
          if (!os_isdir(stackp->ffs_filearray[i]))
            continue;               /* not a directory */
          ff_push(search_ctx,
              ff_create_stack_element(stackp->ffs_filearray[i],
                  stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
        }
      }

      /* we are done with the current directory */
      ff_free_stack_element(stackp);

    }

    /* If we reached this, we didn't find anything downwards.
     * Let's check if we should do an upward search.
     */
    if (search_ctx->ffsc_start_dir
        && search_ctx->ffsc_stopdirs_v != NULL && !got_int) {
      ff_stack_T  *sptr;

      /* is the last starting directory in the stop list? */
      if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
              (int)(path_end - search_ctx->ffsc_start_dir),
              search_ctx->ffsc_stopdirs_v) == TRUE)
        break;

      /* cut of last dir */
      while (path_end > search_ctx->ffsc_start_dir
             && vim_ispathsep(*path_end))
        path_end--;
      while (path_end > search_ctx->ffsc_start_dir
             && !vim_ispathsep(path_end[-1]))
        path_end--;
      *path_end = 0;
      path_end--;

      if (*search_ctx->ffsc_start_dir == 0)
        break;

      STRCPY(file_path, search_ctx->ffsc_start_dir);
      add_pathsep(file_path);
      STRCAT(file_path, search_ctx->ffsc_fix_path);

      /* create a new stack entry */
      sptr = ff_create_stack_element(file_path,
          search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
      ff_push(search_ctx, sptr);
    } else
      break;
  }

  free(file_path);
  return NULL;
}
Exemplo n.º 5
0
Arquivo: sed.c Projeto: DeadZen/qse
static int sed_main (int argc, qse_char_t* argv[])
{
	qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
	qse_sed_t* sed = QSE_NULL;
	qse_fs_t* fs = QSE_NULL;
	qse_size_t script_count;
	int ret = -1;

	xarg_t xarg;
	int xarg_inited = 0;

	ret = handle_args (argc, argv);
	if (ret <= -1) return -1;
	if (ret == 0) return 0;

	ret = -1;

#if defined(QSE_BUILD_DEBUG)
	if (g_failmalloc > 0)
	{
		debug_mmgr.ctx = QSE_NULL;
		mmgr = &debug_mmgr;
	}
	else
#endif
	if (g_memlimit > 0)
	{
		xma_mmgr.ctx = qse_xma_open (QSE_MMGR_GETDFL(), 0, g_memlimit);
		if (xma_mmgr.ctx == QSE_NULL)
		{
			qse_printf (QSE_T("ERROR: cannot open memory heap\n"));
			goto oops;
		}
		mmgr = &xma_mmgr;
	}

	if (g_separate && g_infile_pos > 0 && g_inplace)
	{
		fs = qse_fs_open (mmgr, 0);
		if (fs == QSE_NULL)
		{
			qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open file system handler\n"));
			goto oops;
		}

		if (qse_fs_chdir (fs, QSE_T(".")) <= -1)
		{
			qse_fprintf (QSE_STDERR, 
				QSE_T("ERROR: cannot change direcotry in file system handler\n"));
			goto oops;
		}
	}

	sed = qse_sed_openstdwithmmgr (mmgr, 0, QSE_NULL);
	if (!sed)
	{
		qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open stream editor\n"));
		goto oops;
	}

	qse_sed_setopt (sed, QSE_SED_TRAIT, &g_option);

	if (qse_sed_compstd (sed, g_script.io, &script_count) <= -1)
	{
		const qse_sed_loc_t* errloc;
		const qse_char_t* target;
		qse_char_t exprbuf[128];

		errloc = qse_sed_geterrloc(sed);
	
		if (g_script.io[script_count].type == QSE_SED_IOSTD_FILE)
		{
			target = g_script.io[script_count].u.file.path;
		}
		else 
		{
			/* i dont' use QSE_SED_IOSTD_SIO for input */	
			QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_STR);
			qse_fmtuintmax (exprbuf, QSE_COUNTOF(exprbuf),
				script_count, 10, -1, QSE_T('\0'), QSE_T("expression #"));
			target = exprbuf;
		}

		if (errloc->line > 0 || errloc->colm > 0)
		{
			qse_fprintf (QSE_STDERR, 
				QSE_T("ERROR: cannot compile %s - %s at line %lu column %lu\n"),
				target,
				qse_sed_geterrmsg(sed),
				(unsigned long)errloc->line,
				(unsigned long)errloc->colm
			);
		}
		else
		{
			qse_fprintf (QSE_STDERR, 
				QSE_T("ERROR: cannot compile %s - %s\n"),
				target,
				qse_sed_geterrmsg(sed)
			);
		}
		goto oops;
	}

#if defined(QSE_ENABLE_SEDTRACER)
	if (g_trace) qse_sed_setopt (sed, QSE_SED_TRACER, trace_exec);
#endif

	qse_memset (&xarg, 0, QSE_SIZEOF(xarg));
	xarg.mmgr = qse_sed_getmmgr(sed);
	xarg_inited = 1;

	if (g_separate && g_infile_pos > 0)
	{
		/* 's' and input files are specified on the command line */
		qse_sed_iostd_t out_file;
		qse_sed_iostd_t out_inplace;
		qse_sed_iostd_t* output_file = QSE_NULL;
		qse_sed_iostd_t* output = QSE_NULL;
		int inpos;

		/* a dash is treated specially for QSE_SED_IOSTD_FILE in
		 * qse_sed_execstd(). so make an exception here */
		if (g_output_file && 
		    qse_strcmp (g_output_file, QSE_T("-")) != 0)
		{
			out_file.type = QSE_SED_IOSTD_SIO;
			out_file.u.sio = qse_sio_open (
				qse_sed_getmmgr(sed),
				0,
				g_output_file,
				QSE_SIO_WRITE |
				QSE_SIO_CREATE |
				QSE_SIO_TRUNCATE |
				QSE_SIO_IGNOREMBWCERR
			);
			if (out_file.u.sio == QSE_NULL)
			{
				qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open %s\n"), g_output_file);
				goto oops;
			}

			output_file = &out_file;
			output = output_file;
		}

		/* perform wild-card expansions for non-unix platforms */
		if (expand_wildcards (argc - g_infile_pos, &argv[g_infile_pos], g_wildcard, &xarg) <= -1)
		{
			qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
			goto oops;
		}

		for (inpos = 0; inpos < xarg.size; inpos++)
		{
			qse_sed_iostd_t in[2];
			qse_char_t* tmpl_tmpfile;
			
			in[0].type = QSE_SED_IOSTD_FILE;
			in[0].u.file.path = xarg.ptr[inpos];
			in[0].u.file.cmgr = g_infile_cmgr;
			in[1].type = QSE_SED_IOSTD_NULL;

			tmpl_tmpfile = QSE_NULL;
			if (g_inplace && in[0].u.file.path)
			{
				int retried = 0;

				tmpl_tmpfile = qse_strdup2 (in[0].u.file.path, QSE_T(".XXXX"),  qse_sed_getmmgr(sed));
				if (tmpl_tmpfile == QSE_NULL)
				{
					qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
					goto oops;
				}

			open_temp:
				out_inplace.type = QSE_SED_IOSTD_SIO;
				out_inplace.u.sio = qse_sio_open (
					qse_sed_getmmgr(sed),
					0,
					tmpl_tmpfile,
					QSE_SIO_WRITE |
					QSE_SIO_CREATE |
					QSE_SIO_IGNOREMBWCERR |
					QSE_SIO_EXCLUSIVE |
					QSE_SIO_TEMPORARY
				);
				if (out_inplace.u.sio == QSE_NULL)
				{
					if (retried) 
					{
						qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open %s\n"), tmpl_tmpfile);
						QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
						goto oops;
					}
					else
					{
						/* retry to open the file with shorter names */
						QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
						tmpl_tmpfile = qse_strdup (QSE_T("TMP-XXXX"),  qse_sed_getmmgr(sed));
						if (tmpl_tmpfile == QSE_NULL)
						{
							qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
							goto oops;
						}
						retried = 1;
						goto open_temp;
					}
				}

				output = &out_inplace;
			}

			if (qse_sed_execstd (sed, in, output) <= -1)
			{
				if (output) qse_sio_close (output->u.sio);

				if (tmpl_tmpfile) 
				{
					qse_fs_delfile (fs, tmpl_tmpfile, 0);
					QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
				}
				print_exec_error (sed);
				goto oops;
			}

			if (tmpl_tmpfile)
			{
				QSE_ASSERT (output == &out_inplace);
				qse_sio_close (output->u.sio);
				output = output_file;

				if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file.path) <= -1)
				{
					qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot rename %s to %s. not deleting %s\n"), 
						tmpl_tmpfile, in[0].u.file.path, tmpl_tmpfile);
					QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
					goto oops;
				}

				QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
			}

			if (qse_sed_isstop (sed)) break;
		}

		if (output) qse_sio_close (output->u.sio);
	}
	else
	{
		int xx;
		qse_sed_iostd_t* in = QSE_NULL;
		qse_sed_iostd_t out;

		if (g_infile_pos > 0)
		{
			int i;
			const qse_char_t* tmp;

			/* input files are specified on the command line */

			/* perform wild-card expansions for non-unix platforms */
			if (expand_wildcards (argc - g_infile_pos, &argv[g_infile_pos], g_wildcard, &xarg) <= -1)
			{
				qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
				goto oops;
			}

			in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (xarg.size + 1));
			if (in == QSE_NULL)
			{
				qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
				goto oops;
			}

			for (i = 0; i < xarg.size; i++)
			{
				in[i].type = QSE_SED_IOSTD_FILE;
				tmp = xarg.ptr[i];
				in[i].u.file.path = tmp;
				in[i].u.file.cmgr = g_infile_cmgr;
			}

			in[i].type = QSE_SED_IOSTD_NULL;
		}

		if (g_output_file)
		{
			out.type = QSE_SED_IOSTD_FILE;
			out.u.file.path = g_output_file;
			out.u.file.cmgr = g_outfile_cmgr;
		}
		else
		{
			/* arrange to be able to specify cmgr.
			 * if not for cmgr, i could simply pass QSE_NULL 
			 * to qse_sed_execstd() below like
			 *   xx = qse_sed_execstd (sed, in, QSE_NULL); */
			out.type = QSE_SED_IOSTD_FILE;
			out.u.file.path = QSE_NULL;
			out.u.file.cmgr = g_outfile_cmgr;
		}

		g_sed = sed;
		set_intr_run ();
		xx = qse_sed_execstd (sed, in, &out);
		if (in) QSE_MMGR_FREE (qse_sed_getmmgr(sed), in);
		unset_intr_run ();
		g_sed = QSE_NULL;

		if (xx <= -1)
		{
			print_exec_error (sed);
			goto oops;
		}
	}

	ret = 0;

oops:
	if (xarg_inited) purge_xarg (&xarg);
	if (sed) qse_sed_close (sed);
	if (fs) qse_fs_close (fs);
	if (xma_mmgr.ctx) qse_xma_close (xma_mmgr.ctx);
	free_scripts ();

#if defined(QSE_BUILD_DEBUG)
	if (g_failmalloc > 0)
	{
		qse_fprintf (QSE_STDERR, QSE_T("\n"));
		qse_fprintf (QSE_STDERR, QSE_T("-[MALLOC COUNTS]---------------------------------------\n"));
		qse_fprintf (QSE_STDERR, QSE_T("ALLOC: %lu FREE: %lu: REALLOC: %lu\n"), 
			(unsigned long)debug_mmgr_alloc_count,
			(unsigned long)debug_mmgr_free_count,
			(unsigned long)debug_mmgr_realloc_count);
		qse_fprintf (QSE_STDERR, QSE_T("-------------------------------------------------------\n"));
	}
#endif
	return ret;
}
Exemplo n.º 6
0
/**
 * Parse command line options.
 *
 * @param argv program arguments
 */
void read_options(int argc, char *argv[])
{
	struct parsed_cmd_line_t cmd_line;
#ifdef _WIN32
	int i;
	vector_t *expanded_cnames;
#endif

	memset(&opt, 0, sizeof(opt));
	opt.mem = rsh_vector_new_simple();
	opt.find_max_depth = -1;

	/* initialize cmd_line */
	memset(&cmd_line, 0, sizeof(cmd_line));
	rsh_blocks_vector_init(&cmd_line.options);
	cmd_line.argv = argv;
	cmd_line.argc = argc;

	/* parse command line and apply encoding options */
	parse_cmdline_options(&cmd_line);
	read_config();
	
#ifdef _WIN32
	/* set default encoding if no encoding options were specified, */
	/* this should be done here, even if config file was not found. */
	if( (opt.flags & OPT_ENCODING) == 0 ) opt.flags |= OPT_UTF8;
#endif

	/* note: encoding and -o/-l options are already applied */
	IF_WINDOWS(setup_console());
	setup_output(); /* setup program output */

	apply_cmdline_options(&cmd_line); /* process the rest of command options */

	/* options were processed, so we don't need them anymore */
	rsh_blocks_vector_destroy(&cmd_line.options);
	
#ifdef _WIN32
	expanded_cnames = rsh_vector_new_simple();

	/* convert paths to internal encoding and expand wildcards. */
	for(i = 0; i < cmd_line.n_files; i++) {
		wchar_t* path = cmd_line.files[i];
		wchar_t* p = wcschr(path, L'\0') - 1;

		/* strip trailing '\','/' symbols (if not preceded by ':') */
		for(; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0;
		expand_wildcards(expanded_cnames, path);
	}

	opt.cmd_vec = expanded_cnames;
	opt.files = (char**)expanded_cnames->array;
	opt.n_files = (int)expanded_cnames->size;
	free(cmd_line.files);
	LocalFree(cmd_line.warg);
#else
	opt.files = cmd_line.files;
	opt.n_files = cmd_line.n_files;
	rsh_vector_add_ptr(opt.mem, opt.files);
#endif

	make_final_options_checks();

	set_default_sums_flags(argv[0]); /* detect default hashes from program name */
}
Exemplo n.º 7
0
int process_ssh_request(char *request)
{
	char **av, **tmp_av, **tenv;
	char *flat_request,*tmpstring, *tmprequest;
	char bad_winscp3str[] = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server exec sftp-server";
	int retval;
	int reqlen=strlen(request);
	char **env = NULL;

	debug(LOG_DEBUG, "processing request: \"%s\"\n", request);

	tmprequest=strdup(request);

#ifdef WINSCP_COMPAT			

	bad_winscp3str[57]=10;
	bad_winscp3str[127]=10;
			
	if(strcmp(request,bad_winscp3str)==0)
	{
	    /*
		 * switch out the command to use, winscp wont know the difference
	 	 */
		free(tmprequest);
		tmprequest=strdup(PROG_SFTP_SERVER);
	    syslog(LOG_DEBUG, "winscp3 compat correcting to: \"[%s]\"\n", PROG_SFTP_SERVER);
	}
#endif

	
#ifdef GFTP_COMPAT 
	/*
	 *	gFTP compatibility hack
	 */
	if (NULL != (tmpstring=strbeg(request, "echo -n xsftp ; ")))
	{
		free(tmprequest);
		tmprequest=strdup(tmpstring);
		printf("xsftp");
		fflush(stdout);
	}
#endif

#ifdef RESTRICTIVE_FILENAMES
	/*
	 * we flat out reject special chars
	 */
	if (!valid_chars(tmprequest))
	{
		debug(LOG_DEBUG, "rejected because of invalid chars (%s)", logstamp());
		free(tmprequest);
		return(-1);
	}
#endif

#ifdef WINSCP_COMPAT
	if (strbeg(tmprequest,PROG_CD))
	{
		char *destdir=(char *)malloc(reqlen);
		if (destdir == NULL)
		{
			perror("malloc");
			exit(EXIT_FAILURE);
		}

		/*
		 * well, now that scponly is a persistent shell
		 * i have to maintain a $PWD.  damn.
		 * we're going to INSIST upon a double quote
		 * encapsulated new directory to change to.
		 */
		if ((tmprequest[(reqlen-1)]=='"') && (tmprequest[3]=='"'))
		{
			bzero(destdir,reqlen);
			strncpy(destdir,&tmprequest[4],reqlen-5);
			debug(LOG_INFO, "chdir: %s (%s)", tmprequest, logstamp());
			retval=chdir(destdir);
			free(destdir);
			free(tmprequest);
			return(retval);
		}
		syslog(LOG_ERR, "bogus chdir request: %s (%s)", tmprequest, logstamp());
		free(tmprequest);
		return(-1);
	}
#endif

	/*
	 * convert request string to an arg_vector
	 */
	av = build_arg_vector(tmprequest);

	/*
	 * clean any path info from request and substitute our known pathnames
	 */
	av[0] = substitute_known_path(av[0]);
	
	/*
	 * we only process wildcards for scp commands
	 */
#ifdef ENABLE_WILDCARDS
#ifdef ENABLE_SCP2
	if (exact_match(av[0],PROG_SCP))
		av = expand_wildcards(av);
#endif
#endif

/*
 *	check for a compile time chdir configuration
 */
#ifdef ENABLE_DEFAULT_CHDIR
	if (exact_match(av[0],PROG_SFTP_SERVER))
	{
		syslog(LOG_INFO, "changing initial directory to %s", DEFAULT_CHDIR);
		chdir(DEFAULT_CHDIR);
	}
#endif
	

	flat_request = flatten_vector(av);

	/* 
	 * Use a temp arg vector since getopt will permute the command line arguments
	 * for anything that it does not know about.  If all rsync options are well
	 * defined this isn't necessary.
	 */
	tmp_av = build_arg_vector(flat_request);
	if(check_dangerous_args(tmp_av))
	{
		syslog(LOG_ERR, "requested command (%s) tried to use disallowed argument (%s))", 
			flat_request, logstamp());
		exit(EXIT_FAILURE);
	}
	discard_vector(tmp_av);

	if (valid_arg_vector(av))
	{

/*														   
 * Unison needs the HOME environment variable be set to the directory						  
 * where the .unison directory resides.										
 */														    
#ifdef USE_SAFE_ENVIRONMENT
		safeenv[0] = NULL;
		filter_allowed_env_vars();
		tenv = safeenv;
		if (debuglevel) {
			while (NULL != *tenv) {
				syslog(LOG_DEBUG, "Environment contains \"%s\"", *tenv++);
			}
		}
		env = safeenv;
#endif

#ifdef UNISON_COMPAT
		/* the HOME environment variable should have been set above, but I need to make sure
		 * that it's value as read from the environment is replaced with the actual value
		 * as it exists within the chroot, which is what the applications will expect to see.
		 */
		if (replace_env_entry("HOME",homedir) && (((strlen(homedir) + 6 ) > FILENAME_MAX) || !mysetenv("HOME",homedir)))
		{
			syslog(LOG_ERR, "could not set HOME environment variable (%s)", logstamp());
			exit(EXIT_FAILURE);
		}
		debug(LOG_DEBUG, "set non-chrooted HOME environment variable to %s (%s)", homedir, logstamp());
#endif 
		syslog(LOG_INFO, "running: %s (%s)", flat_request, logstamp());

#ifdef WINSCP_COMPAT
		if (winscp_mode)
		{
			int status=0;
			if (fork() == 0)
				retval=execve(av[0],av,env);
			else
			{
				wait(&status);
				fflush(stdout);
				fflush(stderr);
				discard_vector(av);
#ifdef USE_SAFE_ENVIRONMENT											    
				discard_child_vectors(safeenv);
#endif
				free(flat_request);
				free(tmprequest);
				return(WEXITSTATUS(status));
			}
		}
		else
#endif
		{
			debug(LOG_DEBUG, "about to exec \"%s\" (%s)", av[0], logstamp());
			retval=execve(av[0],av,env);
		}
		syslog(LOG_ERR, "failed: %s with error %s(%u) (%s)", flat_request, strerror(errno), errno, logstamp());
		free(flat_request);
		discard_vector(av);
#ifdef USE_SAFE_ENVIRONMENT
		discard_child_vectors(safeenv);
#endif
#ifdef WINSCP_COMPAT
		if (winscp_mode)
		{
			free(tmprequest);
			return(-1);
		}
		else
#endif 
			exit(errno);
	}

	/*
	 *	reaching this point in the code means the request isnt one of
	 *	our accepted commands
 	 */
	if (debuglevel)
	{
		if (exact_match(flat_request,tmprequest))
			syslog (LOG_ERR, "denied request: %s [%s]", tmprequest, logstamp());
		else
			syslog (LOG_ERR, "denied request: %s (resolved to: %s) [%s]", tmprequest, flat_request, logstamp());
	}
	free(flat_request); 
#ifdef WINSCP_COMPAT
	if (winscp_mode)
	{
		printf ("command not permitted by scponly\n");
		free(tmprequest);
		return(-1);
	}
	else
#endif 
		exit(EXIT_FAILURE);
}