621 lines
18 KiB
C
621 lines
18 KiB
C
/*
|
|
* Copyright (c) 2016, Peter Haag
|
|
* Copyright (c) 2014, Peter Haag
|
|
* Copyright (c) 2009, Peter Haag
|
|
* Copyright (c) 2004-2008, SWITCH - Teleinformatikdienste fuer Lehre und Forschung
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* * Neither the name of the author nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
#include <sys/sem.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/param.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
|
|
#ifdef HAVE_STDINT_H
|
|
#include <stdint.h>
|
|
#endif
|
|
|
|
#ifndef HAVE_SEMUN
|
|
union semun {
|
|
int val; // value for SETVAL
|
|
struct semid_ds *buf; // buffer for IPC_STAT & IPC_SET
|
|
u_short *array; // array for GETALL & SETALL
|
|
};
|
|
#endif
|
|
|
|
#include "util.h"
|
|
#include "bookkeeper.h"
|
|
|
|
static bookkeeper_list_t *bookkeeper_list = NULL;
|
|
|
|
/* function prototypes */
|
|
|
|
static key_t hash(char *str, int flag);
|
|
|
|
static void sem_lock(int sem_set_id);
|
|
|
|
static void sem_unlock(int sem_set_id);
|
|
|
|
static inline bookkeeper_list_t *Get_bookkeeper_list_entry(bookkeeper_t *bookkeeper);
|
|
|
|
/* Create shared memory object and set its size */
|
|
|
|
/* hash: compute hash value of string */
|
|
#define MULTIPLIER 37
|
|
static key_t hash(char *str, int flag) {
|
|
uint32_t h;
|
|
unsigned char *p;
|
|
char cleanPath[MAXPATHLEN];
|
|
|
|
if ( realpath(str, cleanPath) == NULL ) {
|
|
return -1;
|
|
}
|
|
|
|
h = 0;
|
|
for (p = (unsigned char*)cleanPath; *p != '\0'; p++)
|
|
h = MULTIPLIER * h + *p;
|
|
|
|
if ( flag ) {
|
|
h = MULTIPLIER * h + 'R';
|
|
}
|
|
// LogError("Bookeeper hash for path: '%s' -> '%s': %u flag: %i", str, cleanPath, h, flag);
|
|
return (key_t)h; // or, h % ARRAY_SIZE;
|
|
|
|
} // End of hash
|
|
|
|
// locks the semaphore, for exclusive access to the bookkeeping record
|
|
static void sem_lock(int sem_set_id) {
|
|
struct sembuf sem_op;
|
|
|
|
/* wait on the semaphore, unless it's value is non-negative. */
|
|
sem_op.sem_num = 0;
|
|
sem_op.sem_op = -1;
|
|
sem_op.sem_flg = 0;
|
|
if ( semop(sem_set_id, &sem_op, 1) == 0 )
|
|
return;
|
|
|
|
LogError("semop() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
|
|
} // End of sem_lock
|
|
|
|
// sem_unlock. un-locks the semaphore.
|
|
static void sem_unlock(int sem_set_id) {
|
|
struct sembuf sem_op;
|
|
|
|
/* signal the semaphore - increase its value by one. */
|
|
sem_op.sem_num = 0;
|
|
sem_op.sem_op = 1;
|
|
sem_op.sem_flg = 0;
|
|
if ( semop(sem_set_id, &sem_op, 1) == 0 )
|
|
return;
|
|
|
|
LogError("semop() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
|
|
} // End of sem_unlock
|
|
|
|
static inline bookkeeper_list_t *Get_bookkeeper_list_entry(bookkeeper_t *bookkeeper) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( bookkeeper == NULL )
|
|
return NULL;
|
|
|
|
bookkeeper_list_entry = bookkeeper_list;
|
|
while ( bookkeeper_list_entry != NULL && bookkeeper_list_entry->bookkeeper != bookkeeper )
|
|
bookkeeper_list_entry = bookkeeper_list_entry->next;
|
|
|
|
return bookkeeper_list_entry;
|
|
|
|
} // End of Get_bookkeeper_list_entry
|
|
|
|
int InitBookkeeper(bookkeeper_t **bookkeeper, char *path, pid_t nfcapd_pid, pid_t launcher_pid) {
|
|
int sem_key, shm_key, shm_id, sem_id;
|
|
union semun sem_val;
|
|
bookkeeper_list_t **bookkeeper_list_entry;
|
|
|
|
*bookkeeper = NULL;
|
|
|
|
shm_key = hash(path, 0);
|
|
if ( shm_key == - 1 )
|
|
return ERR_PATHACCESS;
|
|
|
|
// check if the shared memory is already allocated
|
|
shm_id = shmget(shm_key, sizeof(bookkeeper_t), 0600);
|
|
|
|
if ( shm_id >= 0 ) {
|
|
// the segment already exists. Either a running process is active
|
|
// or an unclean shutdown happened
|
|
|
|
// map the segement and check the record
|
|
*bookkeeper = (bookkeeper_t *)shmat(shm_id, NULL, 0);
|
|
if ( *bookkeeper == (bookkeeper_t *)-1 ) {
|
|
LogError("shmat() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
if ( (*bookkeeper)->nfcapd_pid <= 0 ) {
|
|
// rubbish or invalid pid of nfcapd process.
|
|
// Assume unclean shutdown or something else. We clean up and take this record.
|
|
memset((void *)(*bookkeeper), 0, sizeof(bookkeeper_t));
|
|
} else {
|
|
// check if the process created this record is still alive
|
|
int ret = kill((*bookkeeper)->nfcapd_pid, 0);
|
|
if ( ret == - 1 ) {
|
|
switch (errno) {
|
|
case ESRCH:
|
|
// process does not exist, we can clean up this record and use it
|
|
memset((void *)(*bookkeeper), 0, sizeof(bookkeeper_t));
|
|
break;
|
|
case EPERM:
|
|
// A process exists, but we are not allowed to signal this process
|
|
LogError("Another collector with pid %i but different user ID is already running, and configured for '%s'",
|
|
(*bookkeeper)->nfcapd_pid, path);
|
|
return ERR_EXISTS;
|
|
break;
|
|
default:
|
|
// This should never happen, but catch it anyway
|
|
LogError("semop() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
} else {
|
|
// process exists;
|
|
LogError("Another collector with pid %i is already running, and configured for '%s'",
|
|
(*bookkeeper)->nfcapd_pid, path);
|
|
return ERR_EXISTS;
|
|
}
|
|
// if we pass this point, we have recycled an existing record
|
|
|
|
}
|
|
} else {
|
|
// no valid shared segment was found
|
|
switch (errno) {
|
|
case ENOENT:
|
|
// this is ok - no shared segemtn exists, we can create a new one below
|
|
break;
|
|
case EACCES:
|
|
// there is such a segment, but we are not allowed to get it
|
|
// Assume it's another nfcapd
|
|
LogError("Access denied to collector bookkeeping record.");
|
|
return ERR_EXISTS;
|
|
break;
|
|
default:
|
|
// This should never happen, but catch it anyway
|
|
LogError("semop() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
// we now create a new segement, this hould not fail now
|
|
shm_id = shmget(shm_key, sizeof(bookkeeper_t), IPC_CREAT | 0600);
|
|
if ( shm_id == - 1 ) {
|
|
// but did anyway - give up
|
|
LogError("shmget() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
*bookkeeper = (bookkeeper_t *)shmat(shm_id, NULL, 0);
|
|
if ( (*bookkeeper) == (bookkeeper_t *)-1 ) {
|
|
LogError("shmget() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
memset((void *)(*bookkeeper), 0, sizeof(bookkeeper_t));
|
|
}
|
|
// at this point we now have a valid record and can proceed
|
|
(*bookkeeper)->nfcapd_pid = nfcapd_pid;
|
|
(*bookkeeper)->launcher_pid = launcher_pid;
|
|
(*bookkeeper)->sequence++;
|
|
|
|
// create semaphore
|
|
|
|
sem_key = hash(path, 1);
|
|
// this should never fail, as we aleady got a key for the shared memory
|
|
if ( sem_key == - 1 ) {
|
|
// .. but catch it anyway .. and release shared memory. something is fishy
|
|
struct shmid_ds buf;
|
|
shmdt((void *)(*bookkeeper));
|
|
shmctl(shm_id, IPC_RMID, &buf);
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
// get the semaphore
|
|
sem_id = semget(sem_key, 1, IPC_CREAT | 0600);
|
|
if ( sem_id == - 1 ) {
|
|
struct shmid_ds buf;
|
|
|
|
// this should not have failed
|
|
LogError("semget() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
|
|
// release shared memory
|
|
shmdt((void *)(*bookkeeper));
|
|
shmctl(shm_id, IPC_RMID, &buf);
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
// initialize the semaphore
|
|
sem_val.val = 1;
|
|
if ( semctl(sem_id, 0, SETVAL, sem_val) == -1) {
|
|
struct shmid_ds buf;
|
|
|
|
// this should not have failed
|
|
LogError("semctl() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
|
|
// release shared memory
|
|
shmdt((void *)(*bookkeeper));
|
|
shmctl(shm_id, IPC_RMID, &buf);
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
bookkeeper_list_entry = &bookkeeper_list;
|
|
while ( *bookkeeper_list_entry != NULL )
|
|
bookkeeper_list_entry = &((*bookkeeper_list_entry)->next);
|
|
|
|
(*bookkeeper_list_entry) = (bookkeeper_list_t *)malloc(sizeof(bookkeeper_list_t));
|
|
if ( !*bookkeeper_list_entry ) {
|
|
struct shmid_ds buf;
|
|
|
|
LogError("malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
shmdt((void *)(*bookkeeper));
|
|
shmctl(shm_id, IPC_RMID, &buf);
|
|
semctl( sem_id, 0, IPC_RMID );
|
|
return ERR_FAILED;
|
|
}
|
|
memset((void *)*bookkeeper_list_entry, 0, sizeof(bookkeeper_list_t));
|
|
|
|
(*bookkeeper_list_entry)->shm_id = shm_id;
|
|
(*bookkeeper_list_entry)->sem_id = sem_id;
|
|
(*bookkeeper_list_entry)->bookkeeper = *bookkeeper;
|
|
(*bookkeeper_list_entry)->next = NULL;
|
|
|
|
// we are done
|
|
return BOOKKEEPER_OK;
|
|
|
|
} // End of InitBookkeeper
|
|
|
|
int AccessBookkeeper(bookkeeper_t **bookkeeper, char *path) {
|
|
bookkeeper_list_t **bookkeeper_list_entry;
|
|
int sem_key, shm_key, shm_id, sem_id;
|
|
|
|
*bookkeeper = NULL;
|
|
|
|
shm_key = hash(path, 0);
|
|
if ( shm_key == - 1 )
|
|
return ERR_PATHACCESS;
|
|
|
|
// check if the shared memory is already allocated
|
|
shm_id = shmget(shm_key, sizeof(bookkeeper_t), 0600);
|
|
|
|
if ( shm_id < 0 ) {
|
|
// the segment does not exists. Check why
|
|
|
|
switch (errno) {
|
|
case ENOENT:
|
|
// no shared segemtn exists.
|
|
return ERR_NOTEXISTS;
|
|
break;
|
|
case EACCES:
|
|
// there is such a segment, but we are not allowed to get it
|
|
// Assume it's another nfcapd
|
|
LogError("Access denied to collector bookkeeping record.");
|
|
return ERR_FAILED;
|
|
break;
|
|
default:
|
|
// This should never happen, but catch it anyway
|
|
LogError("semop() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
// not reached
|
|
}
|
|
// at this point we now have a valid record and can proceed
|
|
|
|
// create semaphore
|
|
sem_key = hash(path, 1);
|
|
// this should never fail, as we aleady got a key for the shared memory
|
|
if ( sem_key == - 1 ) {
|
|
// .. but catch it anyway .. and release shared memory. something is fishy
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
// get the semaphore
|
|
sem_id = semget(sem_key, 1, 0600);
|
|
if ( sem_id == - 1 ) {
|
|
// this should not have failed
|
|
LogError("semget() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
// map the shared segment
|
|
*bookkeeper = (bookkeeper_t *)shmat(shm_id, NULL, 0);
|
|
if ( *bookkeeper == (bookkeeper_t *)-1 ) {
|
|
LogError("shmat() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
|
|
bookkeeper_list_entry = &bookkeeper_list;
|
|
while ( *bookkeeper_list_entry != NULL && (*bookkeeper_list_entry)->bookkeeper != NULL )
|
|
bookkeeper_list_entry = &((*bookkeeper_list_entry)->next);
|
|
|
|
// allocate new slot, else use unused slot
|
|
if ( *bookkeeper_list_entry == NULL ) {
|
|
(*bookkeeper_list_entry) = (bookkeeper_list_t *)malloc(sizeof(bookkeeper_list_t));
|
|
if ( !*bookkeeper_list_entry ) {
|
|
LogError("malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
return ERR_FAILED;
|
|
}
|
|
memset((void *)*bookkeeper_list_entry, 0, sizeof(bookkeeper_list_t));
|
|
}
|
|
|
|
(*bookkeeper_list_entry)->shm_id = shm_id;
|
|
(*bookkeeper_list_entry)->sem_id = sem_id;
|
|
(*bookkeeper_list_entry)->bookkeeper = *bookkeeper;
|
|
(*bookkeeper_list_entry)->next = NULL;
|
|
|
|
return BOOKKEEPER_OK;
|
|
|
|
|
|
} // End of AccessBookkeeper
|
|
|
|
void ReleaseBookkeeper(bookkeeper_t *bookkeeper, int destroy) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
struct shmid_ds buf;
|
|
|
|
if ( !bookkeeper )
|
|
return;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return;
|
|
}
|
|
|
|
// detach from my process addr space memory
|
|
if ( shmdt((void *)bookkeeper) == -1 ) {
|
|
// ups ..
|
|
LogError("shmdt() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
}
|
|
bookkeeper = NULL;
|
|
|
|
if ( destroy == 0 ) {
|
|
// Entry no longer valid
|
|
bookkeeper_list_entry->bookkeeper = NULL;
|
|
bookkeeper_list_entry->shm_id = 0;
|
|
bookkeeper_list_entry->sem_id = 0;
|
|
return;
|
|
}
|
|
|
|
// prevent other proceeses to access the share memory, while we are removing it
|
|
// try to clean up.
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
if ( shmctl(bookkeeper_list_entry->shm_id, IPC_RMID, &buf) ) {
|
|
// ups ..
|
|
LogError("shmctl() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
}
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
if ( semctl( bookkeeper_list_entry->sem_id, 0, IPC_RMID ) == -1 ) {
|
|
// ups ..
|
|
LogError("semctl() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
|
|
}
|
|
|
|
// Entry no longer valid
|
|
bookkeeper_list_entry->bookkeeper = NULL;
|
|
bookkeeper_list_entry->shm_id = 0;
|
|
bookkeeper_list_entry->sem_id = 0;
|
|
|
|
|
|
} // End of ReleaseBookkeeper
|
|
|
|
int LookBooks(bookkeeper_t *bookkeeper) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( !bookkeeper )
|
|
return 0;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return 1;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
|
|
return 0;
|
|
|
|
} // End of LookBooks
|
|
|
|
int UnlookBooks(bookkeeper_t *bookkeeper) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( !bookkeeper )
|
|
return 0;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return 1;
|
|
}
|
|
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
return 0;
|
|
|
|
} // End of UnlookBooks
|
|
|
|
void ClearBooks(bookkeeper_t *bookkeeper, bookkeeper_t *tmp_books) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( !bookkeeper )
|
|
return;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
// backup copy
|
|
if ( tmp_books != NULL ) {
|
|
memcpy((void *)tmp_books, (void *)bookkeeper, sizeof(bookkeeper_t));
|
|
}
|
|
bookkeeper->first = 0;
|
|
bookkeeper->last = 0;
|
|
bookkeeper->numfiles = 0;
|
|
bookkeeper->filesize = 0;
|
|
bookkeeper->sequence++;
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
} // End of ClearBooks
|
|
|
|
uint64_t BookSequence(bookkeeper_t *bookkeeper) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
uint64_t seq;
|
|
|
|
if ( !bookkeeper )
|
|
return 0;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return 0;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
seq = bookkeeper->sequence;
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
return seq;
|
|
|
|
} // End of BookSequence
|
|
|
|
void UpdateBooks(bookkeeper_t *bookkeeper, time_t when, uint64_t size) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( !bookkeeper )
|
|
return;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
if ( bookkeeper->first == 0 )
|
|
bookkeeper->first = when;
|
|
|
|
bookkeeper->last = when;
|
|
bookkeeper->numfiles++;
|
|
bookkeeper->filesize += size;
|
|
bookkeeper->sequence++;
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
} // End of UpdateBooks
|
|
|
|
void UpdateBooksParam(bookkeeper_t *bookkeeper, time_t lifetime, uint64_t maxsize) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
|
|
if ( !bookkeeper )
|
|
return;
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
bookkeeper->max_lifetime = lifetime;
|
|
bookkeeper->max_filesize = maxsize;
|
|
bookkeeper->sequence++;
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
} // End of UpdateBooksParam
|
|
|
|
void PrintBooks(bookkeeper_t *bookkeeper) {
|
|
bookkeeper_list_t *bookkeeper_list_entry;
|
|
struct tm *ts;
|
|
time_t t;
|
|
char string[32];
|
|
|
|
if ( !bookkeeper ) {
|
|
printf("No bookkeeper record available!\n");
|
|
return;
|
|
}
|
|
|
|
bookkeeper_list_entry = Get_bookkeeper_list_entry(bookkeeper);
|
|
if ( !bookkeeper_list_entry ) {
|
|
// this should never happen
|
|
LogError("Software error in %s line %d: %s", __FILE__, __LINE__, "Entry not found in list");
|
|
return;
|
|
}
|
|
|
|
sem_lock(bookkeeper_list_entry->sem_id);
|
|
printf("Collector process: %lu\n", (unsigned long)bookkeeper->nfcapd_pid);
|
|
if ( bookkeeper->launcher_pid )
|
|
printf("Launcher process: %lu\n", (unsigned long)bookkeeper->launcher_pid);
|
|
else
|
|
printf("Launcher process: <none>\n");
|
|
printf("Record sequence : %llu\n", (unsigned long long)bookkeeper->sequence);
|
|
|
|
t = bookkeeper->first;
|
|
ts = localtime(&t);
|
|
strftime(string, 31, "%Y-%m-%d %H:%M:%S", ts);
|
|
string[31] = '\0';
|
|
printf("First : %s\n", bookkeeper->first ? string : "<not set>");
|
|
|
|
t = bookkeeper->last;
|
|
ts = localtime(&t);
|
|
strftime(string, 31, "%Y-%m-%d %H:%M:%S", ts);
|
|
string[31] = '\0';
|
|
printf("Last : %s\n", bookkeeper->last ? string : "<not set>");
|
|
printf("Number of files : %llu\n", (unsigned long long)bookkeeper->numfiles);
|
|
printf("Total file size : %llu\n", (unsigned long long)bookkeeper->filesize);
|
|
printf("Max file size : %llu\n", (unsigned long long)bookkeeper->max_filesize);
|
|
printf("Max life time : %llu\n", (unsigned long long)bookkeeper->max_lifetime);
|
|
sem_unlock(bookkeeper_list_entry->sem_id);
|
|
|
|
} // End of PrintBooks
|
|
|