env.c
author Myhailo Danylenko <isbear@ukrpost.net>
Tue, 03 May 2011 14:44:28 +0300
changeset 21 8b61328ab7c1
parent 18 962e2fc6a708
child 22 b71ca771fa1a
permissions -rw-r--r--
Update versions & add AVV description

/*
 * env.c                -- Tampering with mcabber's environment
 *
 * Copyrigth (C) 2009      Myhailo Danylenko <isbear@ukrpost.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#include <mcabber/commands.h>
#include <mcabber/utils.h>
#include <mcabber/compl.h>
#include <mcabber/logprint.h>
#include <mcabber/modules.h>
#include <mcabber/api.h>

#include "config.h"

void env_load   (void);
void env_unload (void);

#define DESCRIPTION ( "Some debugging routines\nProvides commands /env and /cd" )

static module_info_t info_env_dev = {
	.branch      = "dev",
	.api         = 20,
	.version     = PROJECT_VERSION,
	.description = DESCRIPTION,
	.requires    = NULL,
	.init        = env_load,
	.uninit      = env_unload,
	.next        = NULL,
};

module_info_t info_env = {
	.branch      = "0.10.1",
	.api         = 1,
	.version     = PROJECT_VERSION,
	.description = DESCRIPTION,
	.requires    = NULL,
	.init        = env_load,
	.uninit      = env_unload,
	.next        = &info_env_dev,
};

#ifdef MCABBER_API_HAVE_CMD_ID
static gpointer env_env_cmid = NULL;
static gpointer env_cd_cmid  = NULL;
static gboolean env_env_set_safe = FALSE;
static gboolean env_cd_set_safe  = FALSE;
#endif

extern char **environ;

// /env [option [= [value]]]
static void do_env (char *arg)
{
	if (!*arg) {
		// print full variables list
		GSList  *vars   = NULL;
		int      max    = 0;

		{
			char   **envvar;

			for (envvar = environ; *envvar; ++envvar) {
				char *end = strchr (*envvar, '=');

				if (end) {
					int   len  = end - *envvar;
					char *name = g_strndup (*envvar, len);
	
					if (len > max)
						max = len;

					vars = g_slist_prepend (vars, name);
				}
			}
		}

		if (max) {
			gchar  *format = g_strdup_printf ("Env %%-%ds = %%s", max);
			GSList *eel;

			vars = g_slist_sort (vars, (GCompareFunc) strcmp);

			for (eel = vars; eel; eel = eel->next) {
				char *name  = (char *) eel->data;
				char *value = getenv (name);

				scr_log_print (LPRINT_NORMAL, format, name, value);

				g_free (name);
			}

			g_free (format);
		}

		g_slist_free (vars);

	} else {

		char *varend = strchr (arg, '=');

		if (!varend) {
			// print variable alone
			char *value = getenv (arg);

			if (value)
				scr_log_print (LPRINT_NORMAL, "Env %s = %s", arg, value);

		} else if (varend == arg)

				scr_log_print (LPRINT_NORMAL, "You must specify variable name.");

		else {

			char *argstart = varend + 1;
			char *var;

			for (varend--; varend > arg && *varend == ' '; --varend);

			var = g_strndup (arg, varend - arg + 1);

			while (!*argstart && *argstart == ' ')
				++argstart;

			if (*argstart)
				// set variable
				setenv (var, argstart, 1);
			else
				// unset variable
				unsetenv (var);

			g_free (var);
		}
	}
}

// /cd [path]
static void do_cd (char *arg)
{
	if (!*arg) { // get
		char cwd[256];
		if (getcwd (cwd, 256) == NULL)
			scr_log_print (LPRINT_NORMAL, "Cannot obtain current working directory: %s.", strerror (errno));
		else
			scr_log_print (LPRINT_NORMAL, "%s", cwd);
	} else if (chdir (arg) == -1) // set
		scr_log_print (LPRINT_NORMAL, "Cannot change current working directory: %s.", strerror (errno));
}

void env_load (void)
{
	// command
#ifndef MCABBER_API_HAVE_CMD_ID
	cmd_add ("env", "", 0, 0, do_env, NULL);
	cmd_add ("cd", "", COMPL_FILENAME, 0, do_cd, NULL);
#else
	env_env_cmid = cmd_add ("env", "", 0, 0, do_env, NULL);
	env_cd_cmid  = cmd_add ("cd", "", COMPL_FILENAME, 0, do_cd, NULL);
	env_env_set_safe = cmd_set_safe ("env", TRUE);
	env_cd_set_safe  = cmd_set_safe ("cd",  TRUE);
#endif
}

void env_unload (void)
{
	// command
#ifndef MCABBER_API_HAVE_CMD_ID
	cmd_del ("cd");
	cmd_del ("env");
#else
	if (env_env_cmid)
		cmd_del (env_env_cmid);
	if (env_cd_cmid)
		cmd_del (env_cd_cmid);
	if (env_env_set_safe)
		cmd_set_safe ("env", FALSE);
	if (env_cd_set_safe)
		cmd_set_safe ("cd", FALSE);
#endif
}

/* vim: se ts=4 sw=4: */