|
|
6cf099 |
From d28ed42ad2030090bc511f5b3381b5137885175d Mon Sep 17 00:00:00 2001
|
|
|
6cf099 |
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
|
6cf099 |
Date: Wed, 19 Aug 2015 12:34:08 +0200
|
|
|
6cf099 |
Subject: [PATCH 63/66] TOOLS: add sss_colondb API
|
|
|
6cf099 |
|
|
|
6cf099 |
To simplify import/export users and groups.
|
|
|
6cf099 |
|
|
|
6cf099 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
6cf099 |
---
|
|
|
6cf099 |
src/tools/common/sss_colondb.c | 305 +++++++++++++++++++++++++++++++++++++++++
|
|
|
6cf099 |
src/tools/common/sss_colondb.h | 73 ++++++++++
|
|
|
6cf099 |
2 files changed, 378 insertions(+)
|
|
|
6cf099 |
create mode 100644 src/tools/common/sss_colondb.c
|
|
|
6cf099 |
create mode 100644 src/tools/common/sss_colondb.h
|
|
|
6cf099 |
|
|
|
6cf099 |
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
|
|
|
6cf099 |
new file mode 100644
|
|
|
6cf099 |
index 0000000000000000000000000000000000000000..6b340c80e703342defb8582537db2e4ef3926155
|
|
|
6cf099 |
--- /dev/null
|
|
|
6cf099 |
+++ b/src/tools/common/sss_colondb.c
|
|
|
6cf099 |
@@ -0,0 +1,305 @@
|
|
|
6cf099 |
+/*
|
|
|
6cf099 |
+ Authors:
|
|
|
6cf099 |
+ Pavel Březina <pbrezina@redhat.com>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ Copyright (C) 2015 Red Hat
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
6cf099 |
+ it under the terms of the GNU General Public License as published by
|
|
|
6cf099 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
6cf099 |
+ (at your option) any later version.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is distributed in the hope that it will be useful,
|
|
|
6cf099 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6cf099 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
6cf099 |
+ GNU General Public License for more details.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ You should have received a copy of the GNU General Public License
|
|
|
6cf099 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
6cf099 |
+*/
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include <stdlib.h>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include "util/util.h"
|
|
|
6cf099 |
+#include "util/strtonum.h"
|
|
|
6cf099 |
+#include "tools/common/sss_colondb.h"
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#define IS_STD_FILE(db) ((db)->file == stdin || (db)->file == stdout)
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static char *read_field_as_string(char *line,
|
|
|
6cf099 |
+ const char **_value)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ char *rest;
|
|
|
6cf099 |
+ char *value;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (line == NULL || *line == '\n' || *line == '\0') {
|
|
|
6cf099 |
+ /* There is nothing else to read. */
|
|
|
6cf099 |
+ rest = NULL;
|
|
|
6cf099 |
+ value = NULL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (*line == ':') {
|
|
|
6cf099 |
+ /* Special case for empty value. */
|
|
|
6cf099 |
+ *line = '\0';
|
|
|
6cf099 |
+ rest = line + 1;
|
|
|
6cf099 |
+ value = NULL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Value starts at current position. */
|
|
|
6cf099 |
+ value = line;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Find next field delimiter. */
|
|
|
6cf099 |
+ rest = strchr(line, ':');
|
|
|
6cf099 |
+ if (rest == NULL) {
|
|
|
6cf099 |
+ /* There is no more field. Remove \n from the end. */
|
|
|
6cf099 |
+ rest = strchr(line, '\n');
|
|
|
6cf099 |
+ if (rest != NULL) {
|
|
|
6cf099 |
+ *rest = '\0';
|
|
|
6cf099 |
+ rest = NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Remove it and step one character further. */
|
|
|
6cf099 |
+ *rest = '\0';
|
|
|
6cf099 |
+ rest++;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ *_value = value;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return rest;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static char *read_field_as_uint32(char *line,
|
|
|
6cf099 |
+ uint32_t *_value)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ const char *str;
|
|
|
6cf099 |
+ char *rest;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rest = read_field_as_string(line, &str);
|
|
|
6cf099 |
+ if (str == NULL) {
|
|
|
6cf099 |
+ *_value = 0;
|
|
|
6cf099 |
+ return rest;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ *_value = strtouint32(str, NULL, 10);
|
|
|
6cf099 |
+ if (errno != 0) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse number [%d]: %s\n",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ *_value = 0;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return rest;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb {
|
|
|
6cf099 |
+ FILE *file;
|
|
|
6cf099 |
+ enum sss_colondb_mode mode;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct sss_colondb *db,
|
|
|
6cf099 |
+ struct sss_colondb_read_field *table)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ int readchars;
|
|
|
6cf099 |
+ size_t linelen = 0;
|
|
|
6cf099 |
+ char *line = NULL;
|
|
|
6cf099 |
+ char *tcline;
|
|
|
6cf099 |
+ char *rest;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ int i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (db->mode != SSS_COLONDB_READ) {
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ readchars = getline(&line, &linelen, db->file);
|
|
|
6cf099 |
+ if (readchars == -1) {
|
|
|
6cf099 |
+ /* Nothing was read. */
|
|
|
6cf099 |
+ if (errno != 0) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read line [%d]: %s",
|
|
|
6cf099 |
+ ret, sss_strerror(ret));
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return EOF;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Copy line to mem_ctx. */
|
|
|
6cf099 |
+ tcline = talloc_strdup(mem_ctx, line);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ free(line);
|
|
|
6cf099 |
+ line = NULL;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (tcline == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ rest = tcline;
|
|
|
6cf099 |
+ for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
|
|
|
6cf099 |
+ switch (table[i].type) {
|
|
|
6cf099 |
+ case SSS_COLONDB_UINT32:
|
|
|
6cf099 |
+ rest = read_field_as_uint32(rest, table[i].data.uint32);
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case SSS_COLONDB_STRING:
|
|
|
6cf099 |
+ rest = read_field_as_string(rest, table[i].data.str);
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case SSS_COLONDB_SENTINEL:
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n");
|
|
|
6cf099 |
+ ret = ERR_INTERNAL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (rest == NULL && table[i + 1].type != SSS_COLONDB_SENTINEL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "Line contains less values than expected!\n");
|
|
|
6cf099 |
+ ret = EINVAL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ } else if (rest != NULL && table[i + 1].type == SSS_COLONDB_SENTINEL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
6cf099 |
+ "Line contains more values than expected!\n");
|
|
|
6cf099 |
+ ret = EINVAL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ if (ret != EOK) {
|
|
|
6cf099 |
+ talloc_free(tcline);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+errno_t sss_colondb_writeline(struct sss_colondb *db,
|
|
|
6cf099 |
+ struct sss_colondb_write_field *table)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
6cf099 |
+ char *line = NULL;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+ int i;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (db->mode != SSS_COLONDB_WRITE) {
|
|
|
6cf099 |
+ return ERR_INTERNAL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
6cf099 |
+ if (tmp_ctx == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n");
|
|
|
6cf099 |
+ return ENOMEM;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
|
|
|
6cf099 |
+ switch (table[i].type) {
|
|
|
6cf099 |
+ case SSS_COLONDB_UINT32:
|
|
|
6cf099 |
+ if (table[i].data.uint32 == 0) {
|
|
|
6cf099 |
+ line = talloc_asprintf_append(line, ":");
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ line = talloc_asprintf_append(line, ":%u", table[i].data.uint32);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case SSS_COLONDB_STRING:
|
|
|
6cf099 |
+ if (table[i].data.str == NULL) {
|
|
|
6cf099 |
+ line = talloc_asprintf_append(line, ":");
|
|
|
6cf099 |
+ } else {
|
|
|
6cf099 |
+ line = talloc_asprintf_append(line, ":%s", table[i].data.str);
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case SSS_COLONDB_SENTINEL:
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n");
|
|
|
6cf099 |
+ ret = ERR_INTERNAL;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (line == NULL) {
|
|
|
6cf099 |
+ ret = ENOMEM;
|
|
|
6cf099 |
+ goto done;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ /* Remove starting : */
|
|
|
6cf099 |
+ line++;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ fprintf(db->file, "%s\n", line);
|
|
|
6cf099 |
+ fflush(db->file);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ ret = EOK;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+done:
|
|
|
6cf099 |
+ talloc_free(tmp_ctx);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return ret;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static int sss_colondb_close(void *pvt)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct sss_colondb *db = talloc_get_type(pvt, struct sss_colondb);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (db->file == NULL || IS_STD_FILE(db)) {
|
|
|
6cf099 |
+ return 0;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ fclose(db->file);
|
|
|
6cf099 |
+ db->file = NULL;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return 0;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+static FILE *open_db(const char *filename, enum sss_colondb_mode mode)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ FILE *fp = NULL;
|
|
|
6cf099 |
+ errno_t ret;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ errno = 0;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ switch (mode) {
|
|
|
6cf099 |
+ case SSS_COLONDB_READ:
|
|
|
6cf099 |
+ fp = filename == NULL ? stdin : fopen(filename, "r");
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ case SSS_COLONDB_WRITE:
|
|
|
6cf099 |
+ fp = filename == NULL ? stdout : fopen(filename, "w");
|
|
|
6cf099 |
+ break;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (fp == NULL && filename != NULL) {
|
|
|
6cf099 |
+ ret = errno;
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s [%d]: %s\n",
|
|
|
6cf099 |
+ filename, ret, sss_strerror(ret));
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return fp;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ enum sss_colondb_mode mode,
|
|
|
6cf099 |
+ const char *filename)
|
|
|
6cf099 |
+{
|
|
|
6cf099 |
+ struct sss_colondb *db;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ db = talloc_zero(mem_ctx, struct sss_colondb);
|
|
|
6cf099 |
+ if (db == NULL) {
|
|
|
6cf099 |
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ db->file = open_db(filename, mode);
|
|
|
6cf099 |
+ db->mode = mode;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ if (db->file == NULL) {
|
|
|
6cf099 |
+ talloc_free(db);
|
|
|
6cf099 |
+ return NULL;
|
|
|
6cf099 |
+ }
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ talloc_set_destructor((TALLOC_CTX *)db, sss_colondb_close);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ return db;
|
|
|
6cf099 |
+}
|
|
|
6cf099 |
diff --git a/src/tools/common/sss_colondb.h b/src/tools/common/sss_colondb.h
|
|
|
6cf099 |
new file mode 100644
|
|
|
6cf099 |
index 0000000000000000000000000000000000000000..6edd99cbe3b9ef5c86a48632ac3fc71e8a3e55fe
|
|
|
6cf099 |
--- /dev/null
|
|
|
6cf099 |
+++ b/src/tools/common/sss_colondb.h
|
|
|
6cf099 |
@@ -0,0 +1,73 @@
|
|
|
6cf099 |
+/*
|
|
|
6cf099 |
+ Authors:
|
|
|
6cf099 |
+ Pavel Březina <pbrezina@redhat.com>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ Copyright (C) 2015 Red Hat
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
6cf099 |
+ it under the terms of the GNU General Public License as published by
|
|
|
6cf099 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
6cf099 |
+ (at your option) any later version.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ This program is distributed in the hope that it will be useful,
|
|
|
6cf099 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6cf099 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
6cf099 |
+ GNU General Public License for more details.
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+ You should have received a copy of the GNU General Public License
|
|
|
6cf099 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
6cf099 |
+*/
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#ifndef _SSS_COLONDB_H_
|
|
|
6cf099 |
+#define _SSS_COLONDB_H_
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#include <stdlib.h>
|
|
|
6cf099 |
+#include <stdint.h>
|
|
|
6cf099 |
+#include <errno.h>
|
|
|
6cf099 |
+#include <talloc.h>
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb;
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+enum sss_colondb_mode {
|
|
|
6cf099 |
+ SSS_COLONDB_READ,
|
|
|
6cf099 |
+ SSS_COLONDB_WRITE
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+enum sss_colondb_type {
|
|
|
6cf099 |
+ SSS_COLONDB_UINT32,
|
|
|
6cf099 |
+ SSS_COLONDB_STRING,
|
|
|
6cf099 |
+ SSS_COLONDB_SENTINEL
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+union sss_colondb_write_data {
|
|
|
6cf099 |
+ uint32_t uint32;
|
|
|
6cf099 |
+ const char *str;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+union sss_colondb_read_data {
|
|
|
6cf099 |
+ uint32_t *uint32;
|
|
|
6cf099 |
+ const char **str;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb_write_field {
|
|
|
6cf099 |
+ enum sss_colondb_type type;
|
|
|
6cf099 |
+ union sss_colondb_write_data data;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb_read_field {
|
|
|
6cf099 |
+ enum sss_colondb_type type;
|
|
|
6cf099 |
+ union sss_colondb_read_data data;
|
|
|
6cf099 |
+};
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ enum sss_colondb_mode mode,
|
|
|
6cf099 |
+ const char *filename);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
|
|
|
6cf099 |
+ struct sss_colondb *db,
|
|
|
6cf099 |
+ struct sss_colondb_read_field *table);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+errno_t sss_colondb_writeline(struct sss_colondb *db,
|
|
|
6cf099 |
+ struct sss_colondb_write_field *table);
|
|
|
6cf099 |
+
|
|
|
6cf099 |
+#endif /* _SSS_COLONDB_H_ */
|
|
|
6cf099 |
--
|
|
|
6cf099 |
2.4.3
|
|
|
6cf099 |
|