Beispiel #1
0
//Accept command line arguments
//Determine from second command line argument which procedure to perform
int main(int argc, char* argv[])
{
	char* fileSuffix;
	char* inisearch;
	char* command;
	char* argv2[] = {"", "", ""};

	INILoadManager(argv[argc-1]);

	if(argc == 3) 
	{
		if(strcmp(argv[1], "read") == 0)
		{
			PatchReaderMain(argv[2]);
		}
		else if(strcmp(argv[1], "write") == 0)
		{
			PatchWriterMain(argv);
		}
		else if(strcmp(argv[1], "split") == 0)
		{
			PatchSplitMain(argv[2]);
		}
		else if(strcmp(argv[1], "version") == 0)
		{
			VersionMain(argv[2], 1);
		}
		else if(strcmp(argv[1], "hijack") == 0)
		{
			HijackMain(argv[2]);
		}
		else
		{
			PrintMenu();
		}
	}
	else if(argc == 2)
	{
		//Possible drag & drop here or file association.
		//search in INI for that suffix to see which command to perform
		fileSuffix = GetFileSuffix(argv[1]);
		inisearch = str_join("fileassociations", ":", fileSuffix);
		command = INIGetString(inisearch);
		free(inisearch);

		argv2[0] = argv[0];
		argv2[1] = command;
		argv2[2] = argv[1];

		main(3, argv2);
	}
	else 
	{
		PrintMenu();
	}

	INIDestroyManager();

	return EXIT_SUCCESS;
}
Beispiel #2
0
static char *find_arg(macro *m, char *word, char **args, int *alloced)
{
	*alloced = 0;
	if(!strcmp(word, VA_ARGS_STR)){
		if(args){
			size_t i = dynarray_count(m->args);
			/* if count(args) < i then args[i] is NULL,
			 * which str_join handles
			 */
			*alloced = 1;
			return str_join(args + i, ", ");
		}else{
			return "";
		}
	}

	if(m->args){
		char *w;
		size_t i;

		for(i = 0; (w = m->args[i]); i++)
			if(!strcmp(w, word))
				return args[i]; /* don't expand */
	}

	/* word not found, we use the given identifier */
	return word;
}
Beispiel #3
0
/* read a string from socket. returns malloc()ed buffer with
 \n\r stripped, or NULL on error */
char *Recv (int sock)
{
    char         buf[1024], *p, *result;
    int          n;

reconsider:
    /* see if we already have string ready in the buffer */
    if (leftover != NULL)
    {
        p = strchr (leftover, '\n');
        if (p != NULL)
        {
            *p = '\0';
            result = strdup (leftover);
            str_strip (result, "\r\n");
            memmove (leftover, p+1, strlen(p+1)+1);
            return result;
        }
    }

    n = recv (sock, buf, sizeof(buf)-1, 0);
    /* check for error reading from socket. note that we discard something
     which could still be in the leftover buffer: every valid input line must
     be terminated with \n */
    if (n <= 0)
    {
        if (leftover != NULL) free (leftover);
        leftover = NULL;
        Close (sock);
        return NULL;
    }
    /* we got something */
    buf[n] = '\0';

    /* check if buffer contains NULLs. if yes we are getting some binary data,
     and this is BAD THING */
    if (n != strlen (buf))
    {
        if (leftover != NULL) free (leftover);
        leftover = NULL;
        Close (sock);
        return NULL;
    }

    /* if leftover is present, we concatenate it with recent input and then
     consider result. otherwise we copy the input to leftover and again
     proceed to buffer re-examination */
    if (leftover != NULL)
    {
        p = str_join (leftover, buf);
        free (leftover);
        leftover = p;
    }
    else
    {
        leftover = strdup (buf);
    }
    goto reconsider;
}
Beispiel #4
0
int main() {
    // test str_join
    char a[] = "who are you?";
    char b[] = "hello";
    char *ab = str_join(a, b);
    
    printf("the original strings are: %s\n  %s\n", a, b);
    printf("The string after concatenation is: %s \n", ab);
}
Beispiel #5
0

        
Beispiel #6
0
char *list_to_str(ADTList list, char *(*to_str)(void *)) {
    ADTList str_list = list_new();
    for (ADTListItem it = list_head(list); it; it = list_next(it)) {
        char *str = to_str(list_value(it));
        list_append(str_list, str_escape(str, (char *) ","));
        free(str);
    }
    char *str = str_join(str_list, (char *) ",");
    list_full_release(str_list, free);
    return str;
}
Beispiel #7
0
int main(){
  int len, i;
  char *p[3] = { "Ene", "Mene", "Miste" }, *s, **r;
  s = str_join(p, 3, ", ");
  printf("%s\n", s);
  r = str_split(s, ",", &len);
  printf("\n");
  for(i=0; i<len; i++){
    printf("%s\n", r[i]);
  }
  return 0;
}
Beispiel #8
0
void setheader(vector * vec){
	char * header, * value;
	vector * subvec;
	if(vec->length > 2){
		header = vector_get(vec, 1);
		subvec = subvector(vec, 2, vec->length);
		value = str_join((char**)subvec->data, "", subvec->length);
		map_put(headers, header, value, strlen(value)+1);
		destroy_vector(subvec);
		free(value);
	}
}
Beispiel #9
0
char	*get_full_info(char *name)
{
	struct stat st;
	char		*long_format;

	if (name)
	{
		if (lstat(name, &st) == -1)
			perror("ft_ls error: ");
		else
		{
			long_format = str_join(file_type(&st), file_rights(&st));
			long_format = str_join(long_format, file_nlink(&st));
			long_format = str_join(long_format, file_users(&st));
			long_format = str_join(long_format, file_date(&st));
			return (long_format);
		}
	}
	else
		perror("ft_ls error: ");
	return (NULL);
}
Beispiel #10
0
std::string str_join(const std::vector<std::string> &tokens, const std::string &delim, const bool trim_empty) {
	if (trim_empty) {
		return str_join(str_compact(tokens), delim, false);
	}
	else {
		std::stringstream ss;
		for (size_t i = 0; i < tokens.size() - 1; ++i) {
			ss << tokens[i] << delim;
		}
		ss << tokens[tokens.size() - 1];

		return ss.str();
	}
}
Beispiel #11
0
static	char		*a_rights(struct stat *st)
{
	char	*rights;

	rights = str_dup("---");
	if (rights)
	{
		if (st->st_mode & S_IROTH)
			rights[0] = 'r';
		if (st->st_mode & S_IWOTH)
			rights[1] = 'w';
		if (st->st_mode & S_IXOTH)
			rights[2] = 'x';
		return (str_join(add_color(rights, YELLOW), "  "));
	}
	else
		perror("ft_ls error: ");
	return (NULL);
}
Beispiel #12
0
str_t * list_tostr(list_t *list) {
  str_t *ret;
  str_t *catted;

  if (list) {
    if (!list -> size) {
      ret = str_wrap("<>");
    } else {
      ret = str_copy_chars("<");
      catted = str_join(", ", list, _list_reduce_chars);
      if (ret && catted) {
        str_append(ret, catted);
        str_append_chars(ret, ">");
      }
      str_free(catted);
    }
  } else {
    ret = str_wrap("Null");
  }
  return ret;
}
Beispiel #13
0
static void shell_readline(int argc, char **args) {
	int file_capacity = INIT_FILE_SIZE;
	char *tmpstr = (char*)malloc(file_capacity);
	char *leftover = NULL;
	while (1) {
		init_opline();
		if (leftover != NULL) {
			char *tmptmpstr = myreadline("    ");
			tmpstr = str_join(tmptmpstr, leftover);
			free(leftover);
			leftover = NULL;
			free(tmptmpstr);
			tmptmpstr = NULL;
		} else {
			tmpstr = myreadline(">>> ");
		}
		if (tmpstr == NULL || strcmp(tmpstr, "exit") == 0) {
			break;
		}
		leftover = split_and_exec(argc, args, tmpstr);
	}
	FREE(tmpstr);
}
Beispiel #14
0
static PyObject *
Struct_repr(PyObject *self)
{
    Py_ssize_t i;
    PyObject *inner_repr = NULL;
    PyObject *equals = NULL;
    PyObject *pieces = NULL, *result = NULL;
    PyObject *items = NULL, *s;
    PyTypeObject *type = Py_TYPE(self);

    i = Py_ReprEnter(self);
    if (i < 0) {
        return NULL;
    }

    if (i > 0) {
        inner_repr = str_from_string("...");
        if (inner_repr == NULL)
            goto done;

        result = format_with_type(type, inner_repr);
    }
    else if (((PyDictObject *)self)->ma_used == 0) {
        result = format_with_type(type, NULL);
    }
    else {
        /* basically `dict_repr` but with keyword notation */
        pieces = PyList_New(0);
        if (pieces == NULL)
            goto done;

        equals = str_from_string("=");
        if (equals == NULL)
            goto done;

        items = PyDict_Items(self);
        if (items == NULL)
            goto done;
        if (PyList_Sort(items) < 0)
            goto done;

        for (i = 0; i < PyList_GET_SIZE(items); i++) {
            PyObject *temp, *key, *value;
            int status;

            temp = PyList_GET_ITEM(items, i);
            key = PyTuple_GetItem(temp, 0);
            if (key == NULL)
                goto done;
            value = PyTuple_GetItem(temp, 1);
            if (value == NULL)
                goto done;

            /* Prevent repr from deleting value during key format. */
            Py_INCREF(value);
            s = PyObject_Str(key);
            str_concat(&s, equals);
            str_concat_and_del(&s, PyObject_Repr(value));
            Py_DECREF(value);
            if (s == NULL)
                goto done;
            status = PyList_Append(pieces, s);
            Py_DECREF(s);  /* append created a new ref */
            if (status < 0)
                goto done;
        }

        /* Paste them all together with ", " between. */
        s = str_from_string(", ");
        if (s == NULL)
            goto done;
        inner_repr = str_join(s, pieces);
        Py_DECREF(s);

        if (inner_repr == NULL)
            goto done;

        result = format_with_type(type, inner_repr);
    }

done:
    Py_XDECREF(inner_repr);
    Py_XDECREF(items);
    Py_XDECREF(pieces);
    Py_XDECREF(equals);
    Py_ReprLeave(self);
    return result;
}
Beispiel #15
0
/** Load plugin.
 * The loading is interrupted if any of the plugins does not load properly.
 * The already loaded plugins are *not* unloaded, but kept.
 * @param plugin_list string containing a comma-separated list of plugins
 * to load. The plugin list can contain meta plugins.
 */
void
PluginManager::load(const std::list<std::string> &plugin_list)
{
  for (std::list<std::string>::const_iterator i = plugin_list.begin(); i != plugin_list.end(); ++i) {
		if ( i->length() == 0 ) continue;

		bool try_real_plugin = true;
		if ( __meta_plugins.find(*i) == __meta_plugins.end() ) {
			std::string meta_plugin = __meta_plugin_prefix + *i;
			bool found_meta = false;
			std::list<std::string> pset;
			try {
				if (__config->is_list(meta_plugin.c_str())) {
					std::vector<std::string> tmp = __config->get_strings(meta_plugin.c_str());
					pset.insert(pset.end(), tmp.begin(), tmp.end());
				}
				else
					pset = parse_plugin_list(__config->get_string(meta_plugin.c_str()).c_str());
				found_meta = true;
			} catch (ConfigEntryNotFoundException &e) {
				// no meta plugin defined by that name
	      //printf("No meta plugin defined with the name %s\n", i->c_str());
				try_real_plugin = true;
			}

			if (found_meta) {
				if (pset.size() == 0) {
					throw Exception("Refusing to load an empty meta plugin");
				}
				//printf("Going to load meta plugin %s (%s)\n", i->c_str(), pset.c_str());
				__meta_plugins.lock();
				// Setting has to happen here, so that a meta plugin will not cause an
				// endless loop if it references itself!
				__meta_plugins[*i] = pset;
				__meta_plugins.unlock();
				try {
					LibLogger::log_info("PluginManager", "Loading plugins %s for meta plugin %s",
                              str_join(pset.begin(), pset.end(), ",").c_str(), i->c_str());
					load(pset);
					LibLogger::log_debug("PluginManager", "Loaded meta plugin %s", i->c_str());
					notify_loaded(i->c_str());
				} catch (Exception &e) {
					e.append("Could not initialize meta plugin %s, aborting loading.", i->c_str());
					__meta_plugins.erase_locked(*i);
					throw;
				}
			
				try_real_plugin = false;
			}
		}

    if (try_real_plugin &&
	(find_if(plugins.begin(), plugins.end(), plname_eq(*i)) == plugins.end()))
    {
      try {
	//printf("Going to load real plugin %s\n", i->c_str());
	Plugin *plugin = plugin_loader->load(i->c_str());
	plugins.lock();
	try {
	  thread_collector->add(plugin->threads());
	  plugins.push_back(plugin);
	  plugin_ids[*i] = next_plugin_id++;
	  LibLogger::log_debug("PluginManager", "Loaded plugin %s", i->c_str());
	  notify_loaded(i->c_str());
	} catch (CannotInitializeThreadException &e) {
	  e.append("Plugin >>> %s <<< could not be initialized, unloading", i->c_str());
	  plugins.unlock();
	  plugin_loader->unload(plugin);
	  throw;
	}
	plugins.unlock();
      } catch (Exception &e) {
	MutexLocker lock(__meta_plugins.mutex());
	if ( __meta_plugins.find(*i) == __meta_plugins.end() ) {
	  // only throw exception if no meta plugin with that name has
	  // already been loaded
	  throw;
	}
      }
    }
  }
}
Beispiel #16
0
/* prepare list for fast lookups */
fastlist_t *prepare_fastlist (char **list)
{
    int i, j, current_category, negation, escaped, first_special;
    fastlist_t *fl;
    char   *p, *p1;

    fl = xmalloc (sizeof(fastlist_t));
    /* count total number of rules. we add fictitios rule at the start
     to avoid having rule #0 which is bad for routines which use
     signed integers to indicate positive/negative matches */
    for (i=0; list[i] != NULL; i++)
        ;
    fl->n = i+1;
    fl->ncats = 0;
    fl->rules = xmalloc (sizeof(catrule_t) * fl->n);

    fl->rules[0].type     = RULETYPE_SEPARATOR;
    fl->rules[0].category = 0;
    fl->rules[0].rule = NULL;
    fl->rules[0].len = 0;

    /* process every rule: assign type, possibly convert */
    current_category = 0;
    for (i=1; i<fl->n; i++)
    {
        /* shifted because we inserted one rule! */
        p = list[i-1];

        /* check for separator */
        if (p[0] == '+')
        {
            p++;
            p1 = strchr (p, ' ');
            if (p1 != NULL) *p1 = '\0';
            current_category = atoi (p);
            if (current_category != 0) fl->ncats++;
            if (p1 != NULL) *p1 = ' ';
            fl->rules[i].type = RULETYPE_SEPARATOR;
            fl->rules[i].category = 0;
            fl->rules[i].rule = NULL;
            fl->rules[i].len = 0;
            continue;
        }

        /* check for subcategories list */
        if (p[0] == ':')
        {
            fl->rules[i].type = RULETYPE_SUBCATS;
            fl->rules[i].rule = strdup (p+1);
            fl->rules[i].category = current_category;
            continue;
        }

        /* check for negation */
        if (p[0] == '^')
        {
            p++;
            negation = TRUE;
        }
        else
            negation = FALSE;

        /* if rule does not contain slashes at all, append one at the
         end */
        if (strchr (p, '/') == NULL)
        {
            p = str_join (p, "/*");
        }

        /* see if this rule is simple, exact or complex: lookup
         special chars *, ?, [ */
        escaped = FALSE;
        first_special = -1;
        for (j=0; p[j] != '\0'; j++)
        {
            switch (p[j])
            {
            case '\\':
                if (!escaped) escaped = TRUE;
                break;

            case '?':
            case '*':
            case '[':
                if (!escaped) first_special = j;
                else          escaped = FALSE;
                break;

            default:
                if (escaped) escaped = FALSE;
            }
            if (first_special != -1) break;
        }

        /* no special chars at all? */
        if (first_special == -1)
        {
            if (negation)
                fl->rules[i].type = RULETYPE_MATCH_NEG;
            else
                fl->rules[i].type = RULETYPE_MATCH;
            fl->rules[i].rule = strdup (p);
            kill_escapes (fl->rules[i].rule);
        }
        /* simple rule? (just asterisk at the end) */
        else if (p[first_special] == '*' && p[first_special+1] == '\0')
        {
            if (negation)
                fl->rules[i].type = RULETYPE_SIMPLE_NEG;
            else
                fl->rules[i].type = RULETYPE_SIMPLE;
            fl->rules[i].rule = strdup (p);
            fl->rules[i].rule[first_special] = '\0';
            kill_escapes (fl->rules[i].rule);
        }
        /* everything else is complex */
        else
        {
            if (negation)
                fl->rules[i].type = RULETYPE_COMPLEX_NEG;
            else
                fl->rules[i].type = RULETYPE_COMPLEX;
            fl->rules[i].rule = strdup (p);
        }
        fl->rules[i].category = current_category;
        fl->rules[i].len = strlen (fl->rules[i].rule);
    }

    /* build a sorted list of simple and exact rules. find out
     the shortest rule among them */
    fl->n_simple = 0;
    fl->n_complex = 0;
    for (i=0; i<fl->n; i++)
    {
        if (fl->rules[i].type == RULETYPE_MATCH ||
            fl->rules[i].type == RULETYPE_SIMPLE ||
            fl->rules[i].type == RULETYPE_MATCH_NEG ||
            fl->rules[i].type == RULETYPE_SIMPLE_NEG)
            fl->n_simple++;
        else if (fl->rules[i].type == RULETYPE_COMPLEX ||
            fl->rules[i].type == RULETYPE_COMPLEX_NEG)
            fl->n_complex++;
    }

    if (fl->n_simple > 0)
        fl->simple = xmalloc (sizeof(int) * fl->n_simple);
    if (fl->n_complex > 0)
        fl->complex = xmalloc (sizeof(int) * fl->n_complex);
    fl->n_simple = 0;
    fl->n_complex = 0;
    fl->shortest = 10000000;
    /* j = 0; */
    for (i=0; i<fl->n; i++)
    {
        if (fl->rules[i].type == RULETYPE_MATCH ||
            fl->rules[i].type == RULETYPE_SIMPLE ||
            fl->rules[i].type == RULETYPE_MATCH_NEG ||
            fl->rules[i].type == RULETYPE_SIMPLE_NEG)
        {
            fl->shortest = min1 (fl->shortest, strlen(fl->rules[i].rule));
            fl->simple[fl->n_simple++] = i;
        }
        else if (fl->rules[i].type == RULETYPE_COMPLEX ||
                 fl->rules[i].type == RULETYPE_COMPLEX_NEG)
        {
            fl->complex[fl->n_complex++] = i;
        }
        /* if (fl->rules[i].type == RULETYPE_SEPARATOR) j = i+1; */
    }
    fl1 = fl;
    qsort (fl->simple, fl->n_simple, sizeof(int), cmp_simple);

    return fl;
}
Beispiel #17
0
std::string str_replaceall(const std::string &source, const std::string &target, const std::string &replacement) {
	return str_join(str_split(source, target, false), replacement, false);
}
Beispiel #18
0
char				*file_rights(struct stat *st)
{
	return (str_join(u_rights(st), str_join(g_rights(st), a_rights(st))));
}
Beispiel #19
0
void GetProfileOptions (char *ini_name)
{
    char    *p, buf[16];
    int     i;

    if (infLoad (ini_name) < 0)
    {
        fly_error (M("Error loading %s; terminating"), ini_name);
    }

    // put defaults in place

    for (i=0; i<sizeof(boptions)/sizeof(boptions[0]); i++) *(boptions[i].value) = boptions[i].def;
    for (i=0; i<sizeof(ioptions)/sizeof(ioptions[0]); i++) *(ioptions[i].value) = ioptions[i].def;
    for (i=0; i<sizeof(soptions)/sizeof(soptions[0]); i++) *(soptions[i].value) = soptions[i].def;
    for (i=0; i<sizeof(xoptions)/sizeof(xoptions[0]); i++) if (xoptions[i].def != 255) *(xoptions[i].value) = xoptions[i].def;

    if (fl_opt.is_unix || fl_opt.platform == PLATFORM_OS2_X || fl_opt.platform == PLATFORM_OS2_X11) options.pseudographics = 2;

    // some defaults
    options.psw_file = str_strdup1 (paths.user_libpath, 9);
    str_cats (options.psw_file, "nftp.psw");
    
    options.history_file = str_strdup1 (paths.user_libpath, 9);
    str_cats (options.history_file, "nftp.hst");
    
    // retrieve options
    
    for (i=0; i<sizeof(boptions)/sizeof(boptions[0]); i++)
        infGetBoolean (boptions[i].sect, boptions[i].name, boptions[i].value);

    for (i=0; i<sizeof(ioptions)/sizeof(ioptions[0]); i++)
        infGetInteger (ioptions[i].sect, ioptions[i].name, ioptions[i].value);

    for (i=0; i<sizeof(soptions)/sizeof(soptions[0]); i++)
        infGetString (soptions[i].sect, soptions[i].name, soptions[i].value);
    
    for (i=0; i<sizeof(xoptions)/sizeof(xoptions[0]); i++)
        infGetHexbyte (xoptions[i].sect, xoptions[i].name, (char *)xoptions[i].value);


    if (infGetInteger (sect_psw, "encryption-type", &options.psw_enctype) < 0)
    {
        if (fl_opt.platform != PLATFORM_UNIX_TERM && fl_opt.platform != PLATFORM_UNIX_X11)
            options.psw_enctype = 2;
    }
    
    if (infGetBoolean (sect_options, "query-bfs-attributes-support", &options.query_bfsattrs) < 0)
    {
        if (fl_opt.platform == PLATFORM_BEOS_TERM) options.query_bfsattrs = TRUE;
        else                                       options.query_bfsattrs = FALSE;
    }

    if (options.user_agent == NULL)
    {
        strcpy (buf, NFTP_VERSION);
        str_strip2 (buf, " ");
        options.user_agent = str_join ("NFTP-", buf);
    }
    
    // post-config
    
    if (fl_opt.has_osmenu) fl_opt.menu_onscreen = FALSE;
    
    // INI file editor
    
    if (fl_opt.platform == PLATFORM_OS2_VIO)
    {
        options.texteditor = "tedit.exe";
        infGetString (sect_options, "text-editor-os2vio", &options.texteditor);
    }
    
    if (fl_opt.platform == PLATFORM_OS2_PM)
    {
        options.texteditor = "e.exe";
        infGetString (sect_options, "text-editor-os2pm", &options.texteditor);
    }
    
    if (fl_opt.platform == PLATFORM_OS2_X || fl_opt.platform == PLATFORM_OS2_X11)
    {
        options.texteditor = "xedit.exe";
        infGetString (sect_options, "text-editor-os2x", &options.texteditor);
    }
    
    if (fl_opt.platform == PLATFORM_WIN32_CONS)
    {
        options.texteditor = "Notepad.exe";
        infGetString (sect_options, "text-editor-win32cons", &options.texteditor);
    }

    if (fl_opt.platform == PLATFORM_WIN32_GUI)
    {
        options.texteditor = "Notepad.exe";
        infGetString (sect_options, "text-editor-win32gui", &options.texteditor);
    }

    if (fl_opt.platform == PLATFORM_BEOS_TERM)
    {
        options.texteditor = "vi";
        infGetString (sect_options, "text-editor-beosterm", &options.texteditor);
    }
    
    if (fl_opt.platform == PLATFORM_UNIX_TERM)
    {
        options.texteditor = "vi";
        infGetString (sect_options, "text-editor-unixterm", &options.texteditor);
    }

    if (fl_opt.platform == PLATFORM_UNIX_X11)
    {
        options.texteditor = "xedit";
        infGetString (sect_options, "text-editor-unix_x11", &options.texteditor);
    }

    // others
    
    if (options.log_trans)
    {
        if (infGetString (sect_options, "log-transfers-name", &p) == 0)
        {
            strcpy (options.log_trans_name, p);
            free (p);
        }
        else
        {
            strcpy (options.log_trans_name, paths.user_libpath);
            str_cats (options.log_trans_name, "nftp.fls");
        }
    }
    
    if (infGetString (sect_options, "bookmarks-file", &p) == 0)
    {
        strcpy (options.bmk_name, p);
        free (p);
    }
    else
    {
        strcpy (options.bmk_name, paths.user_libpath);
        str_cats (options.bmk_name, "nftp.bmk");
    }
    
    // registration information
    
    if ((cfg_get_string (CONFIG_NFTP, NULL, "registration-name"))[0] == '\0')
    {
        if (infGetString (sect_registration, "name", &p) == 0)
        {
            cfg_set_string (CONFIG_NFTP, NULL, "registration-name", p);
            free (p);
        }

        if (infGetString (sect_registration, "code", &p) == 0)
        {
            cfg_set_string (CONFIG_NFTP, NULL, "registration-code", p);
            free (p);
        }
    }

    // clear key definition table
    for (i=0; i<sizeof(options.keytable)/sizeof(int); i++)
    {
        options.keytable[i]  = KEY_NOTHING;
        options.keytable2[i] = KEY_NOTHING;
    }
    
    def_key_assignments ();
    key_assignments ();
    
    // retrieve colours
    if ((options.monochrome && !cmdline.colour) || cmdline.monochrome)
    {
        options.attr_pointer_marked_dir = VID_REVERSE;
        options.attr_pointer_marked     = VID_REVERSE;
        options.attr_pointer_dir        = VID_REVERSE;
        options.attr_pointer            = VID_REVERSE;
        options.attr_pointer_desc       = VID_REVERSE;
        options.attr_marked_dir         = VID_BRIGHT;
        options.attr_marked             = VID_BRIGHT;
        options.attr_dir                = VID_NORMAL;
        options.attr_description        = VID_NORMAL;           
        options.attr_                   = VID_NORMAL;           
                                                                
        options.attr_background         = VID_NORMAL;           
        options.attr_status             = VID_NORMAL;
        options.attr_status2            = VID_REVERSE;
        options.attr_statmarked         = VID_REVERSE;
        options.attr_tr_info            = VID_NORMAL;           
        options.attr_help               = VID_REVERSE;          
        options.attr_status_local       = VID_NORMAL;

        options.attr_tp_file     = VID_NORMAL;
        options.attr_tp_dir      = VID_NORMAL;
        options.attr_tp_file_m   = VID_NORMAL;
        options.attr_tp_dir__m   = VID_NORMAL;
        options.attr_tp_file_p   = VID_REVERSE;
        options.attr_tp_dir__p   = VID_REVERSE;
        options.attr_tp_file_mp  = VID_REVERSE;
        options.attr_tp_dir__mp  = VID_REVERSE;
        
        options.attr_cntr_header        = VID_REVERSE;
        options.attr_cntr_resp          = VID_NORMAL;
        options.attr_cntr_cmd           = VID_BRIGHT;
        options.attr_cntr_comment       = VID_BRIGHT;

        options.attr_bmrk_back          = VID_REVERSE;
        options.attr_bmrk_pointer       = VID_NORMAL;
        options.attr_bmrk_hostpath      = VID_REVERSE;
        options.attr_bmrk_hostpath_pointer = VID_BRIGHT;
    }

    infFree ();
}
/** Create a new kernel.
 * The kernel is registered internally under the specified name.
 * It must be destroyed when done with it. Only a single kernel
 * can be created for a particular kernel name.
 * @param kernel_name name by which to register kernel
 * @param use_xoprs run X-OPRS (with graphical user interface) instead
 * of oprs.
 * @param extra_data_path extra directories to add to the OPRS_DATA_PATH
 * environment variable which should be searched for files.
 * @param utils_gdb_delay if true, will set the FAWKES_OPRS_GDB_DELAY environment
 * variable to "true". If mod_utils is loaded it will wait for 10 seconds
 * and print a gdb command to start debugging the kernel process.
 */
void
OpenPRSKernelManager::create_kernel(const std::string &kernel_name, bool use_xoprs,
				    std::list<std::string> &extra_data_path, bool utils_gdb_delay)
{
  if (kernels_.find(kernel_name) != kernels_.end()) {
    throw Exception("OpenPRS kernel '%s' already exists", kernel_name.c_str());
  }

  std::string server_port = boost::str(boost::format("%u") % server_port_);
  std::string mp_port     = boost::str(boost::format("%u") % mp_port_);

  const char *argv[] = { use_xoprs ? "xoprs" : "oprs",
			 "-s", server_host_.c_str(), "-i", server_port.c_str(),
			 "-m", mp_host_.c_str(), "-j", mp_port.c_str(),
			 "-l", "lower",
			 "-n", kernel_name.c_str(),
			 NULL };

  std::list<std::string> data_path;
  try {
    if (config_->is_list("/openprs/kernels/data-path")) {
      std::vector<std::string> pl =
	config_->get_strings("/openprs/kernels/data-path");
      std::for_each(pl.begin(), pl.end(), [&data_path](std::string &p){ data_path.push_back(p); });
    } else {
      std::string cfg_data_path =
	config_->get_string("/openprs/kernels/data-path");
      data_path = str_split_list(cfg_data_path, ':');
    }
  } catch (Exception &e) {} // ignored
  std::list<std::string>::iterator ins_pos = data_path.begin();
  for (auto p : extra_data_path) {
    ins_pos = data_path.insert(ins_pos, p);
  }
  const std::string env_HOME = getenv("HOME");
  for (auto &p : data_path) {
    std::string::size_type pos = 0;
    while ((pos = p.find("$HOME", pos)) != std::string::npos) {
      p.replace(pos, 5, env_HOME);
      pos += env_HOME.length();
    }

    if ((pos = p.find("@BASEDIR@")) != std::string::npos) {
      p.replace(pos, 9, BASEDIR);
    }
    if ((pos = p.find("@FAWKES_BASEDIR@")) != std::string::npos) {
      p.replace(pos, 16, FAWKES_BASEDIR);
    }
    if ((pos = p.find("@RESDIR@")) != std::string::npos) {
      p.replace(pos, 8, RESDIR);
    }
    if ((pos = p.find("@CONFDIR@")) != std::string::npos) {
      p.replace(pos, 9, CONFDIR);
    }
  }
  std::string oprs_data_path = str_join(data_path, ':');

  const char *envp_path_ext[] = { "LD_LIBRARY_PATH", OPENPRS_MOD_DIR,
				  "OPRS_DATA_PATH", oprs_data_path.c_str(), NULL };
  std::vector<std::string> envp_v = envp_copy_expand(environ, envp_path_ext);

  envp_v.push_back(boost::str(boost::format("FAWKES_OPRS_GDB_DELAY=%s") %
			      (utils_gdb_delay ? "true" : "false")));

  const char *envp[envp_v.size() + 1];
  for (unsigned int i = 0; i < envp_v.size(); ++i) {
    envp[i] = envp_v[i].c_str();
    if (envp_v[i].find("OPRS_DATA_PATH=") == 0) {
      logger_->log_info("OpenPRSKernelMgr", "%s data path: %s", kernel_name.c_str(), envp[i]);
    }
  }
  envp[envp_v.size()] = NULL;

  std::string command = command_args_tostring(argv);
  logger_->log_info("OpenPRSKernelMgr", "Running:  %s", command.c_str());

  std::string progname = std::string(use_xoprs ? "XOPRS" : "OPRS") + "-" + kernel_name;

  SubProcess *oprs = NULL;
  std::string oprs_error;
  try {
    oprs = new SubProcess(progname.c_str(), argv[0], argv, (const char **)envp, logger_);
  } catch (Exception &e) {
    oprs = NULL;
    oprs_error = e.what_no_backtrace();
  }

  if (oprs) {
    // give some time for OpenPRS to come up
    usleep(500000);

    kernels_[kernel_name] = oprs;
  } else {
    throw Exception("Failed to initialize OpenPRS kernel '%s' (%s)",
		    kernel_name.c_str(), oprs_error.c_str());
  }
}