|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Copyright (c) 2008, Intel Corporation.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* This program is free software; you can redistribute it and/or modify it
|
|
Packit |
2e24a8 |
* under the terms and conditions of the GNU Lesser General Public License,
|
|
Packit |
2e24a8 |
* version 2.1, as published by the Free Software Foundation.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
Packit |
2e24a8 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
Packit |
2e24a8 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
Packit |
2e24a8 |
* for more details.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
2e24a8 |
* along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit |
2e24a8 |
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
#ifndef _UTILS_H_
|
|
Packit |
2e24a8 |
#define _UTILS_H_
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
#define _GNU_SOURCE
|
|
Packit |
2e24a8 |
#include <sys/types.h>
|
|
Packit |
2e24a8 |
#include <sys/stat.h>
|
|
Packit |
2e24a8 |
#include <sys/param.h>
|
|
Packit |
2e24a8 |
#include <sys/types.h>
|
|
Packit |
2e24a8 |
#include <ctype.h>
|
|
Packit |
2e24a8 |
#include <stdlib.h>
|
|
Packit |
2e24a8 |
#include <stddef.h>
|
|
Packit |
2e24a8 |
#include <stdio.h>
|
|
Packit |
2e24a8 |
#include <stdarg.h>
|
|
Packit |
2e24a8 |
#include <errno.h>
|
|
Packit |
2e24a8 |
#include <unistd.h>
|
|
Packit |
2e24a8 |
#include <dirent.h>
|
|
Packit |
2e24a8 |
#include <string.h>
|
|
Packit |
2e24a8 |
#include <time.h>
|
|
Packit |
2e24a8 |
#include <fcntl.h>
|
|
Packit |
2e24a8 |
#include <malloc.h>
|
|
Packit |
2e24a8 |
#include <pthread.h>
|
|
Packit |
2e24a8 |
#include <limits.h>
|
|
Packit |
2e24a8 |
#include <scsi/sg.h>
|
|
Packit |
2e24a8 |
#include <hbaapi.h>
|
|
Packit |
2e24a8 |
#include <vendorhbaapi.h>
|
|
Packit |
2e24a8 |
#include "fc_types.h"
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Structure for tables encoding and decoding name-value pairs such as enums.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
struct sa_nameval {
|
|
Packit |
2e24a8 |
char *nv_name;
|
|
Packit |
2e24a8 |
u_int32_t nv_val;
|
|
Packit |
2e24a8 |
};
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Structure for integer-indexed tables that can grow.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
struct sa_table {
|
|
Packit |
2e24a8 |
u_int32_t st_size; /* number of entries in table */
|
|
Packit |
2e24a8 |
u_int32_t st_limit; /* end of valid entries in table (public) */
|
|
Packit |
2e24a8 |
void **st_table; /* re-allocatable array of pointers */
|
|
Packit |
2e24a8 |
};
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/*
|
|
Packit |
2e24a8 |
* Function prototypes
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
extern int sa_sys_read_line(const char *, const char *, char *, size_t);
|
|
Packit |
2e24a8 |
extern int sa_sys_write_line(const char *, const char *, const char *);
|
|
Packit |
2e24a8 |
extern int sa_sys_read_u32(const char *, const char *, u_int32_t *);
|
|
Packit |
2e24a8 |
extern int sa_sys_read_u64(const char *, const char *, u_int64_t *);
|
|
Packit |
2e24a8 |
extern int sa_dir_read(char *, int (*)(struct dirent *, void *), void *);
|
|
Packit |
2e24a8 |
extern char *sa_strncpy_safe(char *dest, size_t len,
|
|
Packit |
2e24a8 |
const char *src, size_t src_len);
|
|
Packit |
2e24a8 |
extern const char *sa_enum_decode(char *, size_t,
|
|
Packit |
2e24a8 |
const struct sa_nameval *, u_int32_t);
|
|
Packit |
2e24a8 |
extern int sa_enum_encode(const struct sa_nameval *tp,
|
|
Packit |
2e24a8 |
const char *, u_int32_t *);
|
|
Packit |
2e24a8 |
extern const char *sa_flags_decode(char *, size_t,
|
|
Packit |
2e24a8 |
const struct sa_nameval *, u_int32_t);
|
|
Packit |
2e24a8 |
extern int sa_table_grow(struct sa_table *, u_int32_t index);
|
|
Packit |
2e24a8 |
extern void sa_table_destroy_all(struct sa_table *);
|
|
Packit |
2e24a8 |
extern void sa_table_destroy(struct sa_table *);
|
|
Packit |
2e24a8 |
extern void sa_table_iterate(struct sa_table *tp,
|
|
Packit |
2e24a8 |
void (*handler)(void *ep, void *arg), void *arg);
|
|
Packit |
2e24a8 |
extern void *sa_table_search(struct sa_table *tp,
|
|
Packit |
2e24a8 |
void *(*match)(void *ep, void *arg), void *arg);
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_init(tp) - initialize a table.
|
|
Packit |
2e24a8 |
* @param tp table pointer.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* This just clears a table structure that was allocated by the caller.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline void sa_table_init(struct sa_table *tp)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
memset(tp, 0, sizeof(*tp));
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_lookup(tp, index) - lookup an entry in the table.
|
|
Packit |
2e24a8 |
* @param tp table pointer.
|
|
Packit |
2e24a8 |
* @param index the index in the table to access
|
|
Packit |
2e24a8 |
* @returns the entry, or NULL if the index wasn't valid.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline void *sa_table_lookup(const struct sa_table *tp, u_int32_t index)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
void *ep = NULL;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
if (index < tp->st_limit)
|
|
Packit |
2e24a8 |
ep = tp->st_table[index];
|
|
Packit |
2e24a8 |
return ep;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_lookup_n(tp, n) - find Nth non-empty entry in a table.
|
|
Packit |
2e24a8 |
* @param tp table pointer.
|
|
Packit |
2e24a8 |
* @param n is the entry number, the first non-empty entry is 0.
|
|
Packit |
2e24a8 |
* @returns the entry, or NULL if the end of the table reached first.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline void *sa_table_lookup_n(const struct sa_table *tp, u_int32_t n)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
void *ep = NULL;
|
|
Packit |
2e24a8 |
u_int32_t i;
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
for (i = 0; i < tp->st_limit; i++) {
|
|
Packit |
2e24a8 |
ep = tp->st_table[i];
|
|
Packit |
2e24a8 |
if (ep != NULL && n-- == 0)
|
|
Packit |
2e24a8 |
return ep;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
return NULL;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_insert(tp, index, ep) - Replace or insert an entry in the table.
|
|
Packit |
2e24a8 |
* @param tp table pointer.
|
|
Packit |
2e24a8 |
* @param index the index for the new entry.
|
|
Packit |
2e24a8 |
* @param ep entry pointer.
|
|
Packit |
2e24a8 |
* @returns index on success, or -1 if the insert failed.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* Note: if the table has never been used, and is still all zero, this works.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* Note: perhaps not safe for multithreading. Caller can lock the table
|
|
Packit |
2e24a8 |
* externally, but reallocation can take a while, during which time the
|
|
Packit |
2e24a8 |
* caller may not wish to hold the lock.
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline int sa_table_insert(struct sa_table *tp,
|
|
Packit |
2e24a8 |
u_int32_t index, void *ep)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
if (index >= tp->st_limit && sa_table_grow(tp, index) < 0)
|
|
Packit |
2e24a8 |
return -1;
|
|
Packit |
2e24a8 |
tp->st_table[index] = ep;
|
|
Packit |
2e24a8 |
return index;
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_append(tp, ep) - add entry to table and return index.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* @param tp pointer to sa_table structure.
|
|
Packit |
2e24a8 |
* @param ep pointer to new entry, to be added at the end of the table.
|
|
Packit |
2e24a8 |
* @returns new index, or -1 if table couldn't be grown.
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* See notes on sa_table_insert().
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline int
|
|
Packit |
2e24a8 |
sa_table_append(struct sa_table *tp, void *ep)
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
return sa_table_insert(tp, tp->st_limit, ep);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
/** sa_table_sort(tp, compare) - sort table in place
|
|
Packit |
2e24a8 |
*
|
|
Packit |
2e24a8 |
* @param tp pointer to sa_table structure.
|
|
Packit |
2e24a8 |
* @param compare function to compare two entries. It is called with pointers
|
|
Packit |
2e24a8 |
* to the pointers to the entries to be compared. See qsort(3).
|
|
Packit |
2e24a8 |
*/
|
|
Packit |
2e24a8 |
static inline void
|
|
Packit |
2e24a8 |
sa_table_sort(struct sa_table *tp, int (*compare)(const void **, const void **))
|
|
Packit |
2e24a8 |
{
|
|
Packit |
2e24a8 |
qsort(tp->st_table, tp->st_limit, sizeof(void *),
|
|
Packit |
2e24a8 |
(int (*)(const void *, const void *)) compare);
|
|
Packit |
2e24a8 |
}
|
|
Packit |
2e24a8 |
|
|
Packit |
2e24a8 |
#endif /* _UTILS_H_ */
|