collect.c revision 5ac0162c3af95efa08a07b84ff62ad32842922c7
/*
* Collect variables across events.
*
* usage: collect [--add|--remove] <checkpoint> <id> <idlist>
*
* Adds ID <id> to the list governed by <checkpoint>.
* <id> must be part of the ID list <idlist>.
* If all IDs given by <idlist> are listed (ie collect has been
* invoked for each ID in <idlist>) collect returns 0, the
* number of missing IDs otherwise.
* A negative number is returned on error.
*
* Copyright(C) 2007, Hannes Reinecke <hare@suse.de>
*
* 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.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include "libudev.h"
#include "libudev-private.h"
#include "macro.h"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
enum collect_state {
};
struct _mate {
struct udev_list_node node;
char *name;
enum collect_state state;
};
static struct udev_list_node bunch;
static int debug;
/* This can increase dynamically */
{
}
{
exit(4);
}
static void usage(void)
{
printf("%s [options] <checkpoint> <id> <idlist>\n\n"
"Collect variables across events.\n\n"
" -h --help Print this message\n"
" -a --add Add ID <id> to the list <idlist>\n"
" -r --remove Remove ID <id> from the list <idlist>\n"
" -d --debug Debug to stderr\n\n"
" Adds ID <id> to the list governed by <checkpoint>.\n"
" <id> must be part of the list <idlist>.\n"
" If all IDs given by <idlist> are listed (ie collect has been\n"
" invoked for each ID in <idlist>) collect returns 0, the\n"
" number of missing IDs otherwise.\n"
" On error a negative number is returned.\n\n"
}
/*
* prepare
*
* Prepares the database file
*/
{
char buf[512];
int r, fd;
return -errno;
if (fd < 0)
if (debug)
if (debug)
} else {
if (debug)
}
}
return fd;
}
/*
* Read checkpoint file
*
* Tricky reading this. We allocate a buffer twice as large
* as we're going to read. Then we read into the upper half
* of that buffer and start parsing.
* Once we do _not_ find end-of-work terminator (whitespace
* character) we move the upper half to the lower half,
* adjust the read pointer and read the next bit.
* Quite clever methinks :-)
* I should become a programmer ...
*
* Yes, one could have used fgets() for this. But then we'd
* have to use freopen etc which I found quite tedious.
*/
{
int len;
if (!buf)
return log_oom();
if (debug)
goto restart;
}
if (ptr) {
*ptr = '\0';
ptr++;
continue;
if (debug)
if (!him) {
return log_oom();
}
return log_oom();
}
}
}
if (!ptr)
if (!ptr)
break;
}
return 0;
}
/*
* invite
*
* Adds a new ID 'us' to the internal list,
* marks it as confirmed.
*/
{
struct udev_list_node *him_node;
if (debug)
}
}
}
/*
* reject
*
* Marks the ID 'us' as invalid,
* causing it to be removed when the
* list is written out.
*/
{
struct udev_list_node *him_node;
if (debug)
}
}
}
/*
* kickout
*
* Remove all IDs in the internal list which are not part
* of the list passed via the command line.
*/
static void kickout(void)
{
struct udev_list_node *him_node;
struct udev_list_node *tmp;
}
}
}
/*
* missing
*
* Counts all missing IDs in the internal list.
*/
{
char *buf;
int ret = 0;
struct udev_list_node *him_node;
if (!buf)
return log_oom();
ret++;
} else {
char *tmpbuf;
if (!tmpbuf) {
return log_oom();
}
}
return -1;
}
}
}
return ret;
}
/*
* everybody
*
* Prints out the status of the internal list.
*/
static void everybody(void)
{
struct udev_list_node *him_node;
const char *state = "";
case STATE_NONE:
state = "none";
break;
case STATE_OLD:
state = "old";
break;
case STATE_CONFIRMED:
state = "confirmed";
break;
}
}
}
{
{}
};
int argi;
char *checkpoint, *us;
int fd;
int i;
int ret = EXIT_SUCCESS;
int prune = 0;
char tmpdir[UTIL_PATH_SIZE];
ret = EXIT_FAILURE;
goto exit;
}
while (1) {
int option;
if (option == -1)
break;
switch (option) {
case 'a':
prune = 0;
break;
case 'r':
prune = 1;
break;
case 'd':
debug = 1;
break;
case 'h':
usage();
goto exit;
default:
ret = 1;
goto exit;
}
}
printf("Missing parameter(s)\n");
ret = 1;
goto exit;
}
ret = 2;
goto exit;
}
if (debug)
if (fd < 0) {
ret = 3;
goto out;
}
ret = 2;
goto out;
}
struct udev_list_node *him_node;
}
if (!who) {
if (debug)
if (!him) {
goto out;
}
goto out;
}
} else {
if (debug)
}
}
if (prune)
else
if (debug) {
everybody();
}
kickout();
out:
if (debug)
everybody();
if (ret >= 0)
exit:
return ret;
}