/* Copyright (C) 1998, 1999 Thorsten Kukuk
   This file is part of the nis-tools.
   Author: Thorsten Kukuk <kukuk@suse.de>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#ifndef __NISADDENT_H__
#define __NISADDENT_H__

#include <rpcsvc/nis.h>
#include <stdio.h>

/*
 * Below is silly?
 */
#define NIS_MAXINDEXLEN 255

enum addmode_t {
  NOT_SET    = 0x0000,  /* For error checking */
  MODIFY     = 0x0001,  /* Only add and modify */
  CREATE     = 0x0002,  /* Remove all and then add */
  UPDATE     = 0x0004,  /* Add, modify and delete entries */
  USE_FILE   = 0x0010,  /* Read entry from file */
  USE_YP     = 0x0020,  /* from ypmap */
  USE_PASSWD = 0x0100,  /* use password in /etc/passwd? */
  VERBOSE    = 0x0200,
  IS_DUMP    = 0x1000   /* dump */
};
typedef enum addmode_t addmode_t;

/*
 * divide a line in file with strtok.
 * some line makes multiple lines from one line,
 * thus, use linked list.
 */
struct parsed_t {
  char **pf;
  struct parsed_t *next;
};
typedef struct parsed_t parsed_t;

union gets_t {
    struct {
      char *ypmap;
      char *ypdomain;
    } ypinfo;
    FILE *input;
};
typedef union gets_t gets_t;

struct addinfo_t {
  nis_object *obj;         /* table object */
  int *order;              /* FILE order versus NIS order, 
			      means NIS[order[N]] = FILE[N] */
  int *width;              /* use for dump, columns len */
  addmode_t mode;          /* see above enum */
  gets_t aq_from;          /* use for add, where do I get line from */
  u_int flags;             /* for nis function */

  /* function */
  parsed_t *
  (* parse) (char *buf, struct addinfo_t *addinfo);
  int 
  (* dump) (nis_result *res, struct addinfo_t *addinfo);
  int 
  (* regent) (nis_object *obj, parsed_t *parsed, struct addinfo_t *addinfo);
  int 
  (* getline) (gets_t rfrom, char **line);
};
typedef struct addinfo_t addinfo_t;

#define COLMAX 8

struct specinfo_t {
  char *entname;
  parsed_t *(* parse) (char *buf, struct addinfo_t *addinfo);
  int (* dump) (nis_result *res, struct addinfo_t *addinfo);
  int order[COLMAX];
  int width[COLMAX];
  char *ypmap;
};
typedef struct specinfo_t specinfo_t;

/* convinience */
#define INFO_TA(addinfo) (addinfo)->obj->zo_data.objdata_u.ta_data
#define INFO_MAXCOL(addinfo) INFO_TA(addinfo).ta_maxcol
#define INFO_FLAGS(addinfo, col) INFO_TA(addinfo).ta_cols.ta_cols_val[col].tc_flags
#define INFO_COLNAME(addinfo, col) INFO_TA(addinfo).ta_cols.ta_cols_val[col].tc_name

extern int insert (addinfo_t *addinfo);
extern int dump (addinfo_t *addinfo);

extern int parsed_free (parsed_t *parsed);
extern parsed_t *parsed_malloc (int columns);

extern parsed_t *parse_colon (char *buf, struct addinfo_t *addinfo);
extern parsed_t *parse_serv (char *buf, struct addinfo_t *addinfo);
extern parsed_t *parse_generic (char *buf, struct addinfo_t *addinfo);
extern parsed_t *parse_mltcn (char *buf, struct addinfo_t *addinfo);
extern parsed_t *parse_shadow (char *buf, struct addinfo_t *addinfo);

extern int dump_generic (nis_result *res, struct addinfo_t *addinfo);
extern int dump_colon (nis_result *res, struct addinfo_t *addinfo);
extern int dump_mltcn (nis_result *res, struct addinfo_t *addinfo);
extern int dump_serv (nis_result *res, struct addinfo_t *addinfo);

extern int getline_file (gets_t rfrom, char **line);
extern int getline_yp (gets_t rfrom, char **line);

extern int regent_generic (nis_object *obj, parsed_t *parsed, struct addinfo_t *addinfo);
extern int regent_shadow (nis_object *obj, parsed_t *parsed, struct addinfo_t *addinfo);
extern int regent_passwd (nis_object *obj, parsed_t *parsed, struct addinfo_t *addinfo);

extern int ent_pos (char *en_name, addinfo_t *addinfo);

#ifdef _NEEDS_SPECINFO_DEF_

static specinfo_t specinfo[] = {
  {
    "passwd"   , 
    parse_colon, dump_colon,
    {0, 1, 2, 3, 4, 5, 6, 7}, {0, 0, 0, 0, 0, 0, 0, 0},
    "passwd.byname"
  },
  {
    "shadow",
    parse_shadow, dump_colon,
    {0, 1, 2, 3, 4, 5, 6, 7},  {0, 0, 0, 0, 0, 0, 0, 0}, 
    "shadow.byname"
  },
  {
    "group",
    parse_colon, dump_colon,
    {0, 1, 2, 3}, {0, 0, 0, 0},
    "group.byname"
  },
  {
    "services",
    parse_serv, dump_serv,
    {1, 3, 2, 0, 4}, {16, 8, 8, 16, 0},
    "services.byname"
  },
  {
    "netmasks",
    parse_generic, dump_generic,
    {0, 1, 2}, {20, 20, 0},
    "netmasks.byaddr"
  },
  {
    "networks",
    parse_mltcn, dump_mltcn,
    {1, 2, 0, 3}, {12, 20, 24, 0}, 
    "networks.byname"
  },
  {
    "protocols",
    parse_mltcn, dump_mltcn,
    {1, 2, 0, 3}, {16, 4, 16, 0},
    "protocols.byname"
  },
  {
    "hosts",
    parse_mltcn, dump_mltcn,
    {2, 1, 0, 3}, {20, 20, 20, 0},
    "hosts.byname"
  },
  {
    "rpc",
    parse_mltcn, dump_mltcn,
    {1, 2, 0, 3}, {16, 16, 24, 0}, 
    "rpc.byname"
  },
  {NULL, NULL, NULL, {0}, {0}, NULL}
};

#endif /* _NEEDS_SPECINFO_DEF_ */

#endif /*  __NISADDENT_H__ */
