Example #1
0
void mt_task_queue::bump_prio(gtask const & t, unsigned new_prio) {
    switch (get_state(t).load()) {
        case task_state::Queued:
            if (new_prio < get_prio(t)) {
                auto prio = get_prio(t);
                auto &q = m_queue[prio];
                auto it = std::find(q.begin(), q.end(), t);
                lean_always_assert(it != q.end());
                q.erase(it);
                if (q.empty()) m_queue.erase(prio);

                get_prio(t) = std::min(get_prio(t), new_prio);
                check_deps(t);
                enqueue(t);
            }
            break;
        case task_state::Waiting:
            if (new_prio < get_prio(t)) {
                get_prio(t) = std::min(get_prio(t), new_prio);
                check_deps(t);
            }
            break;
        case task_state::Running: case task_state::Failed: case task_state::Success:
            break;
        default: lean_unreachable();
    }
}
Example #2
0
File: task.c Project: jmbr/gnostic
static void
check_deps(const struct task *orig, const struct task *prev, ast_t expr)
{
	ast_t n;
	struct task *current;
	ast_itor_t itor;

	assert(orig);
	
	itor = new_ast_itor(expr);

	for (n = ast_itor_first(itor); n; n = ast_itor_next(itor)) {
		if (ast_get_type(n) != AST_ID)
			continue;

		current = ast_get_item(n);

		if (strcmp(orig->name, current->name) == 0)
			fatal_error("Circular dependency between `%s' and"
				    " `%s'.\n", prev ? prev->name : orig->name,
				    current->name);

		if (current->expr)
			check_deps(orig, current, current->expr);
	}

	delete_ast_itor(itor);
}
Example #3
0
static BDFSExtInfo* ext_get_info (const gchar *device, GError **error) {
    const gchar *args[4] = {"dumpe2fs", "-h", device, NULL};
    gboolean success = FALSE;
    gchar *output = NULL;
    GHashTable *table = NULL;
    guint num_items = 0;
    BDFSExtInfo *ret = NULL;

    if (!check_deps (&avail_deps, DEPS_DUMPE2FS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
    if (!success) {
        /* error is already populated */
        return FALSE;
    }

    table = parse_output_vars (output, "\n", ":", &num_items);
    g_free (output);
    if (!table || (num_items == 0)) {
        /* something bad happened or some expected items were missing  */
        g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse ext4 file system information");
        if (table)
            g_hash_table_destroy (table);
        return NULL;
    }

    ret = get_ext_info_from_table (table, TRUE);
    if (!ret) {
        g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse ext4 file system information");
        return NULL;
    }

    return ret;
}
Example #4
0
void mt_task_queue::submit_core(gtask const & t, unsigned prio) {
    if (!t) return;
    switch (get_state(t).load()){
        case task_state::Created:
            get_data(t)->m_sched_info.reset(new mt_sched_info(prio));
            if (check_deps(t)) {
                if (get_state(t).load() < task_state::Running) {
                    // TODO(gabriel): we need to give up the lock on m_mutex for this
                    if (false && get_data(t)->m_flags.m_eager_execution) {
                        get_state(t) = task_state::Running;
                        execute(t);
                        handle_finished(t);
                    } else {
                        enqueue(t);
                    }
                }
            } else {
                get_state(t) = task_state::Waiting;
                m_waiting.insert(t);
                notify_queue_changed();
            }
            break;
        case task_state::Waiting: case task_state::Queued:
            bump_prio(t, prio);
            break;
        case task_state::Running: case task_state::Failed: case task_state::Success:
            break;
    }
    lean_always_assert(get_state(t).load() >= task_state::Waiting);
}
Example #5
0
/**
 * bd_fs_ntfs_repair:
 * @device: the device containing the file system to repair
 * @error: (out): place to store error (if any)
 *
 * Returns: whether an NTFS file system on the @device was successfully repaired
 *          (if needed) or not (error is set in that case)
 *
 * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_REPAIR
 */
gboolean bd_fs_ntfs_repair (const gchar *device, GError **error) {
    const gchar *args[4] = {"ntfsfix", "-d", device, NULL};

    if (!check_deps (&avail_deps, DEPS_NTFSFIX_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, NULL, error);
}
Example #6
0
/**
 * bd_fs_ntfs_mkfs:
 * @device: the device to create a new ntfs fs on
 * @extra: (allow-none) (array zero-terminated=1): extra options for the creation (right now
 *                                                 passed to the 'mkntfs' utility)
 * @error: (out): place to store error (if any)
 *
 * Returns: whether a new NTFS fs was successfully created on @device or not
 *
 * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_MKFS
 */
gboolean bd_fs_ntfs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error) {
    const gchar *args[5] = {"mkntfs", "-f", "-F", device, NULL};

    if (!check_deps (&avail_deps, DEPS_MKNTFS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, extra, error);
}
Example #7
0
static gboolean ext_set_label (const gchar *device, const gchar *label, GError **error) {
    const gchar *args[5] = {"tune2fs", "-L", label, device, NULL};

    if (!check_deps (&avail_deps, DEPS_TUNE2FS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, NULL, error);
}
Example #8
0
/**
 * bd_fs_xfs_repair:
 * @device: the device containing the file system to repair
 * @extra: (allow-none) (array zero-terminated=1): extra options for the repair (right now
 *                                                 passed to the 'xfs_repair' utility)
 * @error: (out): place to store error (if any)
 *
 * Returns: whether an xfs file system on the @device was successfully repaired
 *          (if needed) or not (error is set in that case)
 *
 * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_REPAIR
 */
gboolean bd_fs_xfs_repair (const gchar *device, const BDExtraArg **extra, GError **error) {
    const gchar *args[3] = {"xfs_repair", device, NULL};

    if (!check_deps (&avail_deps, DEPS_XFS_REPAIR_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, extra, error);
}
Example #9
0
/**
 * bd_fs_ntfs_set_label:
 * @device: the device containing the file system to set the label for
 * @label: label to set
 * @error: (out): place to store error (if any)
 *
 * Returns: whether the label of the NTFS file system on the @device was
 *          successfully set or not
 *
 * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_SET_LABEL
 */
gboolean bd_fs_ntfs_set_label (const gchar *device, const gchar *label, GError **error) {
    const gchar *args[4] = {"ntfslabel", device, label, NULL};

    if (!check_deps (&avail_deps, DEPS_NTFSLABEL_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, NULL, error);
}
Example #10
0
static gboolean ext_mkfs (const gchar *device, const BDExtraArg **extra, const gchar *ext_version, GError **error) {
    const gchar *args[6] = {"mke2fs", "-t", ext_version, "-F", device, NULL};

    if (!check_deps (&avail_deps, DEPS_MKE2FS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, extra, error);
}
Example #11
0
/*!
  \brief lookup_data() returns the value represented by the lookuptable 
  associated with the passed object and offset
  \param object is the container of parameters we need to do the lookup
  \param offset is the offset into lookuptable
  \returns the value at that offset of the lookuptable
  */
G_MODULE_EXPORT gfloat lookup_data(gconstpointer *object, gint offset)
{
	static gboolean (*check_deps)(gconstpointer *);
	static GHashTable *lookuptable_hash = NULL;
	gconstpointer *dep_obj = NULL;
	LookupTable *lookuptable = NULL;
	gchar *table = NULL;
	gchar *alt_table = NULL;
	gboolean state = FALSE;

	if (!lookuptable_hash)
		lookuptable_hash = (GHashTable *)DATA_GET(global_data,"lookuptables");
	if (!check_deps)
		get_symbol("check_dependancies",(void **)&check_deps);

	table = (gchar *)DATA_GET(object,"lookuptable");
	alt_table = (gchar *)DATA_GET(object,"alt_lookuptable");
	dep_obj = (gconstpointer *)DATA_GET(object,"dep_object");

	g_return_val_if_fail(check_deps,0.0);
	g_return_val_if_fail(lookuptable_hash,0.0);
	g_return_val_if_fail(table,0.0);

	/*
	   if (dep_obj)
	   printf("checking dependancy %s\n",DATA_GET(object,"internal_names"));
	   else
	   printf("no dependancy\n");
	 */

	if (dep_obj) 
	{
		if (check_deps)
			state = check_deps(dep_obj);
		else
		{
			MTXDBG(CRITICAL,_("Could NOT locate \"check_dependancies\" function in any of the plugins, BUG!\n"));
			return 0.0;
		}
	}
	if (state)
	{
		/*printf("ALTERNATE\n");*/
		lookuptable = (LookupTable *)g_hash_table_lookup(lookuptable_hash,alt_table);	
	}
	else
	{
		/*printf("NORMAL\n");*/
		lookuptable = (LookupTable *)g_hash_table_lookup(lookuptable_hash,table);	
	}

	if (!lookuptable)
	{
		MTXDBG(CRITICAL,_("Lookuptable is NULL for control %s\n"),(gchar *) DATA_GET(object,"internal_names"));
		return 0.0;
	}
	return lookuptable->array[offset];
}
Example #12
0
/**
 * bd_fs_xfs_is_tech_avail:
 * @tech: the queried tech
 * @mode: a bit mask of queried modes of operation (#BDFSTechMode) for @tech
 * @error: (out): place to store error (details about why the @tech-@mode combination is not available)
 *
 * Returns: whether the @tech-@mode combination is available -- supported by the
 *          plugin implementation and having all the runtime dependencies available
 */
gboolean bd_fs_xfs_is_tech_avail (BDFSTech tech UNUSED, guint64 mode, GError **error) {
    guint32 required = 0;
    guint i = 0;
    for (i = 0; i <= BD_FS_MODE_LAST; i++)
        if (mode & (1 << i))
            required |= fs_mode_util[i];

    return check_deps (&avail_deps, required, deps, DEPS_LAST, &deps_check_lock, error);
}
Example #13
0
/**
 * bd_fs_xfs_set_label:
 * @device: the device containing the file system to set label for
 * @label: label to set
 * @error: (out): place to store error (if any)
 *
 * Returns: whether the label of xfs file system on the @device was
 *          successfully set or not
 *
 * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_SET_LABEL
 */
gboolean bd_fs_xfs_set_label (const gchar *device, const gchar *label, GError **error) {
    const gchar *args[5] = {"xfs_admin", "-L", label, device, NULL};
    if (!label || (strncmp (label, "", 1) == 0))
        args[2] = "--";

    if (!check_deps (&avail_deps, DEPS_XFS_ADMIN_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    return bd_utils_exec_and_report_error (args, NULL, error);
}
Example #14
0
File: task.c Project: jmbr/gnostic
int
task_check_deps(const struct task *self)
{

	if (!self)
		return -1;

	if (self->expr)
		check_deps(self, NULL, self->expr);

	return 0;
}
Example #15
0
/**
 * bd_s390_dasd_format:
 * @dasd: dasd to format
 * @extra: (allow-none) (array zero-terminated=1): extra options for the formatting (right now
 *                                                 passed to the 'dasdfmt' utility)
 * @error: (out): place to store error (if any)
 *
 * Returns: whether dasdfmt was successful or not
 *
 * Tech category: %BD_S390_TECH_DASD-%BD_S390_TECH_MODE_MODIFY
 */
gboolean bd_s390_dasd_format (const gchar *dasd, const BDExtraArg **extra, GError **error) {
    gboolean rc = FALSE;
    const gchar *argv[8] = {"/sbin/dasdfmt", "-y", "-d", "cdl", "-b", "4096", NULL, NULL};

    if (!check_deps (&avail_deps, DEPS_DASDFMT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    argv[6] = g_strdup_printf ("/dev/%s", dasd);

    rc = bd_utils_exec_and_report_error (argv, extra, error);
    g_free ((gchar *) argv[6]);
    return rc;
}
Example #16
0
/**
 * bd_fs_xfs_check:
 * @device: the device containing the file system to check
 * @error: (out): place to store error (if any)
 *
 * Returns: whether an xfs file system on the @device is clean or not
 *
 * Note: if the file system is mounted it may be reported as unclean even if
 *       everything is okay and there are just some pending/in-progress writes
 *
 * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_CHECK
 */
gboolean bd_fs_xfs_check (const gchar *device, GError **error) {
    const gchar *args[6] = {"xfs_db", "-r", "-c", "check", device, NULL};
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_XFS_DB_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    ret = bd_utils_exec_and_report_error (args, NULL, error);
    if (!ret && *error &&  g_error_matches ((*error), BD_UTILS_EXEC_ERROR, BD_UTILS_EXEC_ERROR_FAILED))
        /* non-zero exit status -> the fs is not clean, but not an error */
        /* TODO: should we check that the device exists and contains an XFS FS beforehand? */
        g_clear_error (error);
    return ret;
}
Example #17
0
static gboolean ext_resize (const gchar *device, guint64 new_size, const BDExtraArg **extra, GError **error) {
    const gchar *args[4] = {"resize2fs", device, NULL, NULL};
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_RESIZE2FS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    if (new_size != 0)
        /* resize2fs doesn't understand bytes, just 512B sectors */
        args[2] = g_strdup_printf ("%"G_GUINT64_FORMAT"s", new_size / 512);
    ret = bd_utils_exec_and_report_error (args, extra, error);

    g_free ((gchar *) args[2]);
    return ret;
}
Example #18
0
/**
 * bd_fs_ntfs_check:
 * @device: the device containing the file system to check
 * @error: (out): place to store error (if any)
 *
 * Returns: whether an ntfs file system on the @device is clean or not
 *
 * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_CHECK
 */
gboolean bd_fs_ntfs_check (const gchar *device, GError **error) {
    const gchar *args[4] = {"ntfsfix", "-n", device, NULL};
    gint status = 0;
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_NTFSFIX_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    ret = bd_utils_exec_and_report_status_error (args, NULL, &status, error);
    if (!ret && (status == 1)) {
        /* no error should be reported for exit code 1 -- Recoverable errors have been detected */
        g_clear_error (error);
    }
    return ret;
}
Example #19
0
/**
 * bd_s390_is_tech_avail:
 * @tech: the queried tech
 * @mode: a bit mask of queried modes of operation (#BDS390TechMode) for @tech
 * @error: (out): place to store error (details about why the @tech-@mode combination is not available)
 *
 * Returns: whether the @tech-@mode combination is available -- supported by the
 *          plugin implementation and having all the runtime dependencies available
 */
gboolean bd_s390_is_tech_avail (BDS390Tech tech, guint64 mode, GError **error) {
    switch (tech) {
    case BD_S390_TECH_ZFCP:
        /* all ZFCP-mode combinations are supported by this implementation of the
         * plugin, nothing extra is needed */
        return TRUE;
    case BD_S390_TECH_DASD:
        if (mode & BD_S390_TECH_MODE_MODIFY)
            return check_deps (&avail_deps, DEPS_DASDFMT_MASK, deps, DEPS_LAST, &deps_check_lock, error);
        else
            return TRUE;
    default:
        g_set_error (error, BD_S390_ERROR, BD_S390_ERROR_TECH_UNAVAIL, "Unknown technology");
        return FALSE;
    }
}
Example #20
0
static gboolean ext_repair (const gchar *device, gboolean unsafe, const BDExtraArg **extra, GError **error) {
    /* Force checking even if the file system seems clean. AND
     *     Automatically repair what can be safely repaired. OR
     *     Assume an answer of `yes' to all questions. */
    const gchar *args_progress[7] = {"e2fsck", "-f", unsafe ? "-y" : "-p", "-C", "1", device, NULL};
    const gchar *args[5] = {"e2fsck", "-f", unsafe ? "-y" : "-p", device, NULL};
    gint status = 0;

    if (!check_deps (&avail_deps, DEPS_E2FSCK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    if (bd_utils_prog_reporting_initialized ()) {
        return bd_utils_exec_and_report_progress (args_progress, extra, extract_e2fsck_progress, &status, error);
    } else {
        return bd_utils_exec_and_report_status_error (args, extra, &status, error);
    }
}
Example #21
0
/*!
  \brief lookup_data_obj() returns the value represented by the lookuptable 
  associated with the passed object and offset
  \param object is the container of parameters we need to do the lookup
  \param offset is the offset into lookuptable
  \returns the value at that offset of the lookuptable
  */
G_MODULE_EXPORT gfloat lookup_data_obj(GObject *object, gint offset)
{
	gconstpointer *dep_obj = NULL;
	LookupTable *lookuptable = NULL;
	gchar *table = NULL;
	gchar *alt_table = NULL;
	gboolean state = FALSE;
	static gboolean (*check_deps)(gconstpointer *);

	ENTER();
	if (!check_deps)
		get_symbol("check_dependencies",(void **)&check_deps);

	table = (gchar *)OBJ_GET(object,"lookuptable");
	alt_table = (gchar *)OBJ_GET(object,"alt_lookuptable");
	dep_obj = (gconstpointer *)OBJ_GET(object,"dep_object");


	if (dep_obj) 
	{
		if (check_deps)
			state = check_deps(dep_obj);
		else
			MTXDBG(CRITICAL,_("Could NOT locate \"check_dependencies\" function in any of the plugins, BUG!\n"));
	}
	if (state)
	{
		/*printf("ALTERNATE\n");*/
		lookuptable = (LookupTable *)g_hash_table_lookup((GHashTable *)DATA_GET(global_data,"lookuptables"),alt_table);	
	}
	else
	{
		/*printf("NORMAL\n");*/
		lookuptable = (LookupTable *)g_hash_table_lookup((GHashTable *)DATA_GET(global_data,"lookuptables"),table);	
	}

	if (!lookuptable)
	{
		MTXDBG(CRITICAL,_("Lookuptable is NULL for control %s\n"),(gchar *) DATA_GET(object,"internal_names"));
		EXIT();
		return 0.0;
	}
	EXIT();
	return lookuptable->array[offset];
}
Example #22
0
/**
 * bd_fs_ntfs_resize:
 * @device: the device the file system of which to resize
 * @new_size: new requested size for the file system in bytes (if 0, the file system
 *            is adapted to the underlying block device)
 * @error: (out): place to store error (if any)
 *
 * Returns: whether the file system on @device was successfully resized or not
 *
 * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_RESIZE
 */
gboolean bd_fs_ntfs_resize (const gchar *device, guint64 new_size, GError **error) {
    const gchar *args[5] = {"ntfsresize", NULL, NULL, NULL, NULL};
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_NTFSRESIZE_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    if (new_size != 0) {
        args[1] = "-s";
        args[2] = g_strdup_printf ("%"G_GUINT64_FORMAT, new_size);
        args[3] = device;
    } else {
        args[1] = device;
    }
    ret = bd_utils_exec_and_report_error (args, NULL, error);

    g_free ((gchar *) args[2]);
    return ret;
}
Example #23
0
void mt_task_queue::handle_finished(gtask const & t) {
    lean_always_assert(get_state(t).load() > task_state::Running);
    lean_always_assert(get_data(t));

    if (!get_data(t)->m_sched_info)
        return;  // task has never been submitted

    m_waiting.erase(t);
    get_sched_info(t).notify();

    for (auto & rdep : get_sched_info(t).m_reverse_deps) {
        switch (get_state(rdep).load()) {
            case task_state::Waiting: case task_state::Queued:
                if (check_deps(rdep)) {
                    m_waiting.erase(rdep);
                    if (get_state(rdep).load() < task_state::Running) {
                        lean_always_assert(get_data(rdep));
                        // TODO(gabriel): we need to give up the lock on m_mutex for this
                        if (false && get_data(rdep)->m_flags.m_eager_execution) {
                            get_state(rdep) = task_state::Running;
                            execute(rdep);
                            handle_finished(rdep);
                        } else {
                            enqueue(rdep);
                        }
                    }
                }
                break;
            case task_state::Failed:
                // TODO(gabriel): removed failed tasks from reverse dependency lists?
                m_waiting.erase(rdep);
                break;
            case task_state::Success:
                // this can happen if a task occurs in more than one reverse dependency list,
                // or gets submitted more than once
                break;
            default: lean_unreachable();
        }
    }

    clear(t);
}
Example #24
0
/**
 * bd_fs_xfs_resize:
 * @mpoint: the mount point of the file system to resize
 * @new_size: new requested size for the file system *in file system blocks* (see bd_fs_xfs_get_info())
 *            (if 0, the file system is adapted to the underlying block device)
 * @extra: (allow-none) (array zero-terminated=1): extra options for the resize (right now
 *                                                 passed to the 'xfs_growfs' utility)
 * @error: (out): place to store error (if any)
 *
 * Returns: whether the file system mounted on @mpoint was successfully resized or not
 *
 * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_RESIZE
 */
gboolean bd_fs_xfs_resize (const gchar *mpoint, guint64 new_size, const BDExtraArg **extra, GError **error) {
    const gchar *args[5] = {"xfs_growfs", NULL, NULL, NULL, NULL};
    gchar *size_str = NULL;
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_XFS_GROWFS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    if (new_size != 0) {
        args[1] = "-D";
        /* xfs_growfs doesn't understand bytes, just a number of blocks */
        size_str = g_strdup_printf ("%"G_GUINT64_FORMAT, new_size);
        args[2] = size_str;
        args[3] = mpoint;
    } else
        args[1] = mpoint;

    ret = bd_utils_exec_and_report_error (args, extra, error);

    g_free (size_str);
    return ret;
}
Example #25
0
static gboolean ext_check (const gchar *device, const BDExtraArg **extra, GError **error) {
    /* Force checking even if the file system seems clean. AND
     * Open the filesystem read-only, and assume an answer of no to all
     * questions. */
    const gchar *args_progress[7] = {"e2fsck", "-f", "-n", "-C", "1", device, NULL};
    const gchar *args[5] = {"e2fsck", "-f", "-n", device, NULL};
    gint status = 0;
    gboolean ret = FALSE;

    if (!check_deps (&avail_deps, DEPS_E2FSCK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    if (bd_utils_prog_reporting_initialized ()) {
        ret = bd_utils_exec_and_report_progress (args_progress, extra, extract_e2fsck_progress, &status, error);
    } else {
        ret = bd_utils_exec_and_report_status_error (args, extra, &status, error);
    }

    if (!ret && (status == 4)) {
        /* no error should be reported for exit code 4 - File system errors left uncorrected */
        g_clear_error (error);
    }
    return ret;
}
Example #26
0
/*!
 \brief convert_temps() changes the values of controls based on the currently
 selected temperature scale.  IT works for labels, spinbuttons, etc...
 \param widget (gpointer) pointer to the widget that contains the necessary
 paramaters re temp (Alt label, etc)
 \param units (gpointer) the temp scale selected
 */
G_MODULE_EXPORT void convert_temps(gpointer widget, gpointer units)
{
	static void (*update_widget_f)(gpointer, gpointer);
	static gboolean (*check_deps)(gconstpointer *) = NULL;
	gconstpointer *dep_obj = NULL;
	gfloat upper = 0.0;
	gfloat lower = 0.0;
	gfloat value = 0.0;
	gchar * text = NULL;
	GtkAdjustment * adj = NULL;
	gboolean state = FALSE;
	gint widget_temp = -1;
	/*extern GdkColor black;*/
	extern gconstpointer *global_data;

	/* If this widgt depends on anything call check_dependancy which will
	 * return TRUE/FALSE.  True if what it depends on is in the matching
	 * state, FALSE otherwise...
	 */
	if ((!widget) || (DATA_GET(global_data,"leaving")))
		return;
	if (!check_deps)
		if (!get_symbol("check_dependancies",(void *)&check_deps))
			dbg_func(CRITICAL|CONVERSIONS,g_strdup_printf(__FILE__": convert_temps()\n\tCan NOT locate \"check_dependancies\" function pointer in plugins, BUG!\n"));
	if (!update_widget_f)
		if(!get_symbol("update_widget",(void *)&update_widget_f))
			dbg_func(CRITICAL|CONVERSIONS,g_strdup_printf(__FILE__": convert_temps()\n\tCan NOT locate \"update_widget\" function pointer in plugins, BUG!\n"));
	dep_obj = (gconstpointer *)OBJ_GET(widget,"dep_object");
	widget_temp = (GINT)OBJ_GET(widget,"widget_temp");
	if (dep_obj)
	{
		if (check_deps)
			state = check_deps(dep_obj);
		else
			dbg_func(CRITICAL|CONVERSIONS,g_strdup_printf(__FILE__": convert_temps()\n\tWidget %s has dependant object bound but can't locate function ptr for \"check_dependancies\" from plugins, BUG!\n",glade_get_widget_name(widget)));
	}

	switch ((TempUnits)units)
	{
		case FAHRENHEIT:
			/*printf("fahr %s\n",glade_get_widget_name(widget));*/
			if (GTK_IS_LABEL(widget))
			{
				if ((dep_obj) && (state))	
					text = (gchar *)OBJ_GET(widget,"alt_f_label");
				else
					text = (gchar *)OBJ_GET(widget,"f_label");
				gtk_label_set_text(GTK_LABEL(widget),text);
				//gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));

			}
			if ((GTK_IS_SPIN_BUTTON(widget)) && (widget_temp != FAHRENHEIT))
			{

				adj = (GtkAdjustment *) gtk_spin_button_get_adjustment(
						GTK_SPIN_BUTTON(widget));
				upper = adj->upper;
				value = adj->value;
				lower = adj->lower;
				if (widget_temp == CELSIUS)
				{
					adj->value = c_to_f(value);
					adj->lower = c_to_f(lower);
					adj->upper = c_to_f(upper);
				}
				else /* Previous is kelvin */
				{
					adj->value = k_to_f(value);
					adj->lower = k_to_f(lower);
					adj->upper = k_to_f(upper);
				}

				gtk_adjustment_changed(adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_ENTRY(widget)) && (widget_temp != FAHRENHEIT))
			{
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_RANGE(widget)) && (widget_temp != FAHRENHEIT))
			{
				adj = (GtkAdjustment *) gtk_range_get_adjustment(
						GTK_RANGE(widget));
				upper = adj->upper;
				lower = adj->lower;
				value = adj->value;
				if (widget_temp == CELSIUS)
				{
					adj->value = c_to_f(value);
					adj->lower = c_to_f(lower);
					adj->upper = c_to_f(upper);
				}
				else /* Previous is kelvin */
				{
					adj->value = k_to_f(value);
					adj->lower = k_to_f(lower);
					adj->upper = k_to_f(upper);
				}

				gtk_range_set_adjustment(GTK_RANGE(widget),adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
			}
			break;
		case CELSIUS:
			/*printf("fahr %s\n",glade_get_widget_name(widget));*/
			if (GTK_IS_LABEL(widget))
			{
				if ((dep_obj) && (state))	
					text = (gchar *)OBJ_GET(widget,"alt_c_label");
				else
					text = (gchar *)OBJ_GET(widget,"c_label");
				gtk_label_set_text(GTK_LABEL(widget),text);
				//gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));

			}
			if ((GTK_IS_SPIN_BUTTON(widget)) && (widget_temp != CELSIUS))
			{

				adj = (GtkAdjustment *) gtk_spin_button_get_adjustment(
						GTK_SPIN_BUTTON(widget));
				upper = adj->upper;
				value = adj->value;
				lower = adj->lower;
				if (widget_temp == FAHRENHEIT)
				{
					adj->value = f_to_c(value);
					adj->lower = f_to_c(lower);
					adj->upper = f_to_c(upper);
				}
				else /* Previous is kelvin */
				{
					adj->value = k_to_c(value);
					adj->lower = k_to_c(lower);
					adj->upper = k_to_c(upper);
				}

				gtk_adjustment_changed(adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_ENTRY(widget)) && (widget_temp != CELSIUS))
			{
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_RANGE(widget)) && (widget_temp != CELSIUS))
			{
				adj = (GtkAdjustment *) gtk_range_get_adjustment(
						GTK_RANGE(widget));
				upper = adj->upper;
				lower = adj->lower;
				value = adj->value;
				if (widget_temp == FAHRENHEIT)
				{
					adj->value = f_to_c(value);
					adj->lower = f_to_c(lower);
					adj->upper = f_to_c(upper);
				}
				else /* Previous is kelvin */
				{
					adj->value = k_to_c(value);
					adj->lower = k_to_c(lower);
					adj->upper = k_to_c(upper);
				}

				gtk_range_set_adjustment(GTK_RANGE(widget),adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
			}
			break;
		case KELVIN:
			/*printf("fahr %s\n",glade_get_widget_name(widget));*/
			if (GTK_IS_LABEL(widget))
			{
				if ((dep_obj) && (state))	
					text = (gchar *)OBJ_GET(widget,"alt_k_label");
				else
					text = (gchar *)OBJ_GET(widget,"k_label");
				gtk_label_set_text(GTK_LABEL(widget),text);
				//gtk_widget_modify_text(widget,GTK_STATE_NORMAL,&black);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));

			}
			if ((GTK_IS_SPIN_BUTTON(widget)) && (widget_temp != KELVIN))
			{

				adj = (GtkAdjustment *) gtk_spin_button_get_adjustment(
						GTK_SPIN_BUTTON(widget));
				upper = adj->upper;
				value = adj->value;
				lower = adj->lower;
				if (widget_temp == FAHRENHEIT)
				{
					adj->value = f_to_k(value);
					adj->lower = f_to_k(lower);
					adj->upper = f_to_k(upper);
				}
				else /* Previous is celsius */
				{
					adj->value = c_to_k(value);
					adj->lower = c_to_k(lower);
					adj->upper = c_to_k(upper);
				}

				gtk_adjustment_changed(adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_ENTRY(widget)) && (widget_temp != KELVIN))
			{
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
				update_widget_f(widget,NULL);
			}
			if ((GTK_IS_RANGE(widget)) && (widget_temp != KELVIN))
			{
				adj = (GtkAdjustment *) gtk_range_get_adjustment(
						GTK_RANGE(widget));
				upper = adj->upper;
				lower = adj->lower;
				value = adj->value;
				if (widget_temp == FAHRENHEIT)
				{
					adj->value = f_to_k(value);
					adj->lower = f_to_k(lower);
					adj->upper = f_to_k(upper);
				}
				else /* Previous is celsius */
				{
					adj->value = c_to_k(value);
					adj->lower = c_to_k(lower);
					adj->upper = c_to_k(upper);
				}

				gtk_range_set_adjustment(GTK_RANGE(widget),adj);
				OBJ_SET(widget,"widget_temp",GINT_TO_POINTER(units));
			}
			break;
	}
}
Example #27
0
int
exec_check(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
	match_t match = MATCH_EXACT;
	int flags = PKG_LOAD_BASIC;
	int ret;
	int ch;
	bool yes = false;
	bool dcheck = false;
	bool checksums = false;
	bool recompute = false;
	bool reanalyse_shlibs = false;
	bool shlibs;
	int nbpkgs = 0;
	int i;
	int verbose = 0;

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

	while ((ch = getopt(argc, argv, "yagdBxsrv")) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'y':
			yes = true;
			break;
		case 'd':
			dcheck = true;
			flags |= PKG_LOAD_DEPS;
			break;
		case 'B':
			pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);
			if (!shlibs)
				errx(EX_USAGE, "reanalyzing shlibs requires SHLIBS"
					       " in pkg.conf.");
			reanalyse_shlibs = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 's':
			checksums = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 'r':
			recompute = true;
			flags |= PKG_LOAD_FILES;
			if (geteuid() != 0)
				errx(EX_USAGE, "recomputing the checksums"
				    " and size can only be done as root");
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			usage_check();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	/* Default to all packages if no pkg provided */
	if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) {
		match = MATCH_ALL;
	} else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) {
		usage_check();
		return (EX_USAGE);
	}

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret == EPKG_ENODB) {
		if (geteuid() == 0)
			return (EX_IOERR);

		return (EX_OK);
	}

	if (ret != EPKG_OK)
		return (EX_IOERR);

	i = 0;
	do {
		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			pkgdb_close(db);
			return (EX_IOERR);
		}

		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			const char *pkgname = NULL;
			pkg_get(pkg, PKG_NAME, &pkgname);
			/* check for missing dependencies */
			if (dcheck) {
				if (verbose)
					printf("Checking dependencies: %s\n", pkgname);
				nbpkgs += check_deps(db, pkg, &dh);
			}
			if (checksums) {
				if (verbose)
					printf("Checking checksums: %s\n", pkgname);
				pkg_test_filesum(pkg);
			}
			if (recompute) {
				if (verbose)
					printf("Recomputing size and checksums: %s\n", pkgname);
				pkg_recompute(db, pkg);
			}
			if (reanalyse_shlibs) {
				if (verbose)
					printf("Reanalyzing files for shlibs: %s\n", pkgname);
				if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK)
					printf("Failed to reanalyse for shlibs: %s\n", pkgname);
			}
		}

		if (geteuid() == 0 && nbpkgs > 0) {
			if (yes == false)
				pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);

			printf("\n>>> Missing package dependencies were detected.\n");
			printf(">>> Found %d issue(s) in total with your package database.\n\n", nbpkgs);
			ret = fix_deps(db, &dh, nbpkgs, yes);
			if (ret == EPKG_OK)
				check_summary(db, &dh);
			else if (ret == EPKG_ENODB) {
				db = NULL;
				return (EX_IOERR);
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

	deps_free(&dh);
	pkg_free(pkg);
	pkgdb_close(db);

	return (EX_OK);
}
Example #28
0
/**
 * bd_fs_xfs_get_info:
 * @device: the device containing the file system to get info for (device must
            be mounted, trying to get info for an unmounted device will result
            in an error)
 * @error: (out): place to store error (if any)
 *
 * Returns: (transfer full): information about the file system on @device or
 *                           %NULL in case of error
 *
 * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_QUERY
 */
BDFSXfsInfo* bd_fs_xfs_get_info (const gchar *device, GError **error) {
    const gchar *args[4] = {"xfs_admin", "-lu", device, NULL};
    gboolean success = FALSE;
    gchar *output = NULL;
    BDFSXfsInfo *ret = NULL;
    gchar **lines = NULL;
    gchar **line_p = NULL;
    gboolean have_label = FALSE;
    gboolean have_uuid = FALSE;
    gchar *val_start = NULL;
    gchar *val_end = NULL;
    g_autofree gchar* mountpoint = NULL;

    if (!check_deps (&avail_deps, DEPS_XFS_ADMIN_MASK, deps, DEPS_LAST, &deps_check_lock, error))
        return FALSE;

    mountpoint = bd_fs_get_mountpoint (device, error);
    if (mountpoint == NULL) {
        if (*error == NULL) {
            g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOT_MOUNTED,
                         "Can't get xfs file system information for '%s': Device is not mounted.", device);
            return NULL;
        } else {
            g_prefix_error (error, "Error when trying to get mountpoint for '%s': ", device);
            return NULL;
        }
    }

    success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
    if (!success)
        /* error is already populated */
        return FALSE;

    ret = g_new0 (BDFSXfsInfo, 1);
    lines = g_strsplit (output, "\n", 0);
    g_free (output);
    for (line_p=lines; line_p && *line_p && (!have_label || !have_uuid); line_p++) {
        if (!have_label && g_str_has_prefix (*line_p, "label")) {
            /* extract label from something like this: label = "TEST_LABEL" */
            val_start = strchr (*line_p, '"');
            if (val_start)
                val_end = strchr(val_start + 1, '"');
            if (val_start && val_end) {
                ret->label = g_strndup (val_start + 1, val_end - val_start - 1);
                have_label = TRUE;
            }
        } else if (!have_uuid && g_str_has_prefix (*line_p, "UUID")) {
            /* get right after the "UUID = " prefix */
            val_start = *line_p + 7;
            ret->uuid = g_strdup (val_start);
            have_uuid = TRUE;
        }
    }
    g_strfreev (lines);

    args[0] = "xfs_info";
    args[1] = mountpoint;
    args[2] = NULL;
    success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
    if (!success) {
        /* error is already populated */
        bd_fs_xfs_info_free (ret);
        return FALSE;
    }

    lines = g_strsplit (output, "\n", 0);
    g_free (output);
    line_p = lines;
    /* find the beginning of the (data) section we are interested in */
    while (line_p && *line_p && !g_str_has_prefix (*line_p, "data"))
        line_p++;
    if (!line_p || !(*line_p)) {
        /* error is already populated */
        g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information");
        g_strfreev (lines);
        bd_fs_xfs_info_free (ret);
        return FALSE;
    }

    /* extract data from something like this: "data     =      bsize=4096   blocks=262400, imaxpct=25" */
    val_start = strchr (*line_p, '=');
    val_start++;
    while (isspace (*val_start))
        val_start++;
    if (g_str_has_prefix (val_start, "bsize")) {
        val_start = strchr (val_start, '=');
        val_start++;
        ret->block_size = g_ascii_strtoull (val_start, NULL, 0);
    } else {
        /* error is already populated */
        g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information");
        g_strfreev (lines);
        bd_fs_xfs_info_free (ret);
        return FALSE;
    }
    while (isdigit (*val_start) || isspace(*val_start))
        val_start++;
    if (g_str_has_prefix (val_start, "blocks")) {
        val_start = strchr (val_start, '=');
        val_start++;
        ret->block_count = g_ascii_strtoull (val_start, NULL, 0);
    } else {
        /* error is already populated */
        g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information");
        g_strfreev (lines);
        bd_fs_xfs_info_free (ret);
        return FALSE;
    }
    g_strfreev (lines);

    return ret;
}
Example #29
0
int
exec_check(int argc, char **argv)
{
	struct pkg *pkg = NULL;
	struct pkgdb_it *it = NULL;
	struct pkgdb *db = NULL;
	match_t match = MATCH_EXACT;
	int flags = PKG_LOAD_BASIC;
	int ret, rc = EX_OK;
	int ch;
	bool yes;
	bool dcheck = false;
	bool checksums = false;
	bool recompute = false;
	bool reanalyse_shlibs = false;
	bool noinstall = false;
	int nbpkgs = 0;
	int i;
	int verbose = 0;

	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);

	struct deps_head dh = STAILQ_HEAD_INITIALIZER(dh);

	while ((ch = getopt(argc, argv, "yagidnBxsrv")) != -1) {
		switch (ch) {
		case 'a':
			match = MATCH_ALL;
			break;
		case 'B':
			reanalyse_shlibs = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 'd':
			dcheck = true;
			flags |= PKG_LOAD_DEPS;
			break;
		case 'g':
			match = MATCH_GLOB;
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
		case 'n':
			noinstall = true;
			break;
		case 'r':
			recompute = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 's':
			checksums = true;
			flags |= PKG_LOAD_FILES;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'x':
			match = MATCH_REGEX;
			break;
		case 'y':
			yes = true;
			break;
		default:
			usage_check();
			return (EX_USAGE);
		}
	}
	argc -= optind;
	argv += optind;

	/* Default to all packages if no pkg provided */
	if (argc == 0 && (dcheck || checksums || recompute || reanalyse_shlibs)) {
		match = MATCH_ALL;
	} else if ((argc == 0 && match != MATCH_ALL) || !(dcheck || checksums || recompute || reanalyse_shlibs)) {
		usage_check();
		return (EX_USAGE);
	}

	if (recompute || reanalyse_shlibs)
		ret = pkgdb_access(PKGDB_MODE_READ|PKGDB_MODE_WRITE,
				   PKGDB_DB_LOCAL);
	else
		ret = pkgdb_access(PKGDB_MODE_READ, PKGDB_DB_LOCAL);

	if (ret == EPKG_ENODB) {
		warnx("No packages installed.  Nothing to do!");
		return (EX_OK);
	} else if (ret == EPKG_ENOACCESS) {
		warnx("Insufficient privileges to access the package database");
		return (EX_NOPERM);
	} else if (ret != EPKG_OK) {
		warnx("Error accessing the package database");
		return (EX_SOFTWARE);
	}

	ret = pkgdb_open(&db, PKGDB_DEFAULT);
	if (ret != EPKG_OK)
		return (EX_IOERR);

	i = 0;
	do {
		if ((it = pkgdb_query(db, argv[i], match)) == NULL) {
			pkgdb_close(db);
			return (EX_IOERR);
		}

		while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
			/* check for missing dependencies */
			if (dcheck) {
				if (verbose)
					pkg_printf("Checking dependencies: %n\n", pkg);
				nbpkgs += check_deps(db, pkg, &dh, noinstall);
				if (noinstall && nbpkgs > 0) {
					rc = EX_UNAVAILABLE;
				}
			}
			if (checksums) {
				if (verbose)
					pkg_printf("Checking checksums: %n\n", pkg);
				if (pkg_test_filesum(pkg) != EPKG_OK) {
					rc = EX_DATAERR;
				}
			}
			if (recompute) {
				if (verbose)
					pkg_printf("Recomputing size and checksums: %n\n", pkg);
				if (pkg_recompute(db, pkg) != EPKG_OK) {
					rc = EX_DATAERR;
				}
			}
			if (reanalyse_shlibs) {
				if (verbose)
					pkg_printf("Reanalyzing files for shlibs: %n\n", pkg);
				if (pkgdb_reanalyse_shlibs(db, pkg) != EPKG_OK) {
					pkg_printf("Failed to reanalyse for shlibs: %n\n", pkg);
					rc = EX_UNAVAILABLE;
				}
			}
		}

		if (dcheck && nbpkgs > 0 && !noinstall) {
			printf("\n>>> Missing package dependencies were detected.\n");
			printf(">>> Found %d issue(s) in the package database.\n\n", nbpkgs);

			ret = fix_deps(db, &dh, nbpkgs, yes);
			if (ret == EPKG_OK)
				check_summary(db, &dh);
			else if (ret == EPKG_ENODB) {
				db = NULL;
				return (EX_IOERR);
			}
		}
		pkgdb_it_free(it);
		i++;
	} while (i < argc);

	deps_free(&dh);
	pkg_free(pkg);
	pkgdb_close(db);

	return (rc);
}
Example #30
0
extern int dpkg_main(int argc, char **argv)
{
	deb_file_t **deb_file = NULL;
	status_node_t *status_node;
	int opt = 0;
	int package_num;
	int dpkg_opt = 0;
	int deb_count = 0;
	int state_status;
	int status_num;
	int i;

	while ((opt = getopt(argc, argv, "CF:ilPru")) != -1) {
		switch (opt) {
			case 'C': // equivalent to --configure in official dpkg
				dpkg_opt |= dpkg_opt_configure;
				dpkg_opt |= dpkg_opt_package_name;
				break;
			case 'F': // equivalent to --force in official dpkg
				if (strcmp(optarg, "depends") == 0) {
					dpkg_opt |= dpkg_opt_force_ignore_depends;
				}				
			case 'i':
				dpkg_opt |= dpkg_opt_install;
				dpkg_opt |= dpkg_opt_filename;
				break;
			case 'l':
				dpkg_opt |= dpkg_opt_list_installed;
			case 'P':
				dpkg_opt |= dpkg_opt_purge;
				dpkg_opt |= dpkg_opt_package_name;
				break;
			case 'r':
				dpkg_opt |= dpkg_opt_remove;
				dpkg_opt |= dpkg_opt_package_name;
				break;
			case 'u':	/* Equivalent to --unpack in official dpkg */
				dpkg_opt |= dpkg_opt_unpack;
				dpkg_opt |= dpkg_opt_filename;
				break;
			default:
				show_usage();
		}
	}

	if ((argc == optind) || (dpkg_opt == 0)) {
		show_usage();
	} 

	puts("(Reading database ... xxxxx files and directories installed.)");
	index_status_file("/var/lib/dpkg/status");

	/* Read arguments and store relevant info in structs */
	deb_file = xmalloc(sizeof(deb_file_t));
	while (optind < argc) {
		deb_file[deb_count] = (deb_file_t *) xmalloc(sizeof(deb_file_t));
		if (dpkg_opt & dpkg_opt_filename) {
			deb_file[deb_count]->filename = xstrdup(argv[optind]);
			deb_file[deb_count]->control_file = deb_extract(argv[optind], stdout, (extract_control_tar_gz | extract_one_to_buffer), NULL, "./control");
			if (deb_file[deb_count]->control_file == NULL) {
				error_msg_and_die("Couldnt extract control file");
			}
			package_num = fill_package_struct(deb_file[deb_count]->control_file);

			if (package_num == -1) {
				error_msg("Invalid control file in %s", argv[optind]);
				continue;
			}
			deb_file[deb_count]->package = (unsigned int) package_num;
			/* Add the package to the status hashtable */
			if ((dpkg_opt & dpkg_opt_unpack) || (dpkg_opt & dpkg_opt_install)) {
				status_node = (status_node_t *) xmalloc(sizeof(status_node_t));
				status_node->package = deb_file[deb_count]->package;
				/* use reinstreq isnt changed to "ok" until the package control info
				 * is written to the status file*/
				status_node->status = search_name_hashtable("install reinstreq not-installed");

				status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
				status_hashtable[status_num] = status_node;
			}
		}
		else if (dpkg_opt & dpkg_opt_package_name) {
			deb_file[deb_count]->filename = NULL;
			deb_file[deb_count]->control_file = NULL;
			deb_file[deb_count]->package = search_package_hashtable(
				search_name_hashtable(argv[optind]),
				search_name_hashtable("ANY"), VER_ANY);
			if (package_hashtable[deb_file[deb_count]->package] == NULL) {
				error_msg_and_die("Package %s is uninstalled or unknown\n", argv[optind]);
			}
			state_status = get_status(search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]), 3);

			/* check package status is "installed" */
			if (dpkg_opt & dpkg_opt_remove) {
				if ((strcmp(name_hashtable[state_status], "not-installed") == 0) ||
					(strcmp(name_hashtable[state_status], "config-files") == 0)) {
					error_msg_and_die("%s is already removed.", name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
				}
			}
			else if (dpkg_opt & dpkg_opt_purge) {
				/* if package status is "conf-files" then its ok */
				if (strcmp(name_hashtable[state_status], "not-installed") == 0) {
					error_msg_and_die("%s is already purged.", name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
				}
			}
		}
		deb_count++;
		optind++;
	}
	deb_file[deb_count] = NULL;

	/* Check that the deb file arguments are installable */
	/* TODO: check dependencies before removing */
	if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {
		if (!check_deps(deb_file, 0, deb_count)) {
			error_msg_and_die("Dependency check failed");
		}
	}

	for (i = 0; i < deb_count; i++) {
		/* Remove or purge packages */
		if (dpkg_opt & dpkg_opt_remove) {
			remove_package(deb_file[i]->package);
		}
		else if (dpkg_opt & dpkg_opt_purge) {
			purge_package(deb_file[i]->package);
		}
		else if (dpkg_opt & dpkg_opt_unpack) {
			unpack_package(deb_file[i]);
		}
		else if (dpkg_opt & dpkg_opt_install) {
			unpack_package(deb_file[i]);
			configure_package(deb_file[i]);
		}
		else if (dpkg_opt & dpkg_opt_configure) {
			configure_package(deb_file[i]);
		}
	}

	write_status_file(deb_file);

	for (i = 0; i < deb_count; i++) {
		free(deb_file[i]->control_file);
		free(deb_file[i]->filename);
		free(deb_file[i]);
	}
	free(deb_file);

	for (i = 0; i < NAME_HASH_PRIME; i++) {
		if (name_hashtable[i] != NULL) {
			free(name_hashtable[i]);
		}
	}

	for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
		free_package(package_hashtable[i]);
	}

	for (i = 0; i < STATUS_HASH_PRIME; i++) {
		if (status_hashtable[i] != NULL) {
			free(status_hashtable[i]);
		}
	}

	return(EXIT_FAILURE);
}