/********************************************************
 * File: crashexport.c
 * Created at Sun Jan 28 22:10:33 MSK 2001 by raorn // raorn@binec.ru
 * CrashExport utility
 * $Id: crashexport.c,v 1.16 2001/11/26 01:53:06 raorn Exp $
 *******************************************************/
#include <machine/defs.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#elif HAVE_SYS_TIME
# include <sys/time.h>
#else
# include <time.h>
#endif
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#else
# include <shared/getopt.h>
#endif

#include <shared/jbstrcpy.h>
#include <shared/mystrncpy.h>
#include <shared/node4d.h>

uchar verstr[] = "CrashExport/" PLATFORM_NAME " " VERSION;

bool diskfull;

uchar *cfgbuf;

#define AREATYPE_NETMAIL  1
#define AREATYPE_ECHOMAIL 2
#define AREATYPE_DEFAULT  3
#define AREATYPE_BAD      4
#define AREATYPE_LOCAL    5

uchar tagname[100], desc[100], msgbase[10], path[100], export[1000], aka[50];
uchar group, areatype;
uchar *groups = NULL;
bool unconfirmed;

#define FORMAT_AREASBBS       0
#define FORMAT_FORWARD        1
#define FORMAT_FORWARDNODESC  2
#define FORMAT_GOLDED         3

int format;

bool CheckFlags(uchar group, uchar * node)
{
  int c;

  for (c = 0; c < strlen(node); c++) {
    if (toupper(group) == toupper(node[c]))
      return (TRUE);
  }

  return (FALSE);
}

void writearea(FILE *fh)
{
  int c;
  uchar escdesc[100];

  uchar *gedmsgbase, *gedtype, *gedflags;
  uchar gedgroupbuf[10];

  /* Never write unconfirmed areas to output file */
  if (unconfirmed)
    return;

  /* Never write default areas to output file */
  if (areatype == AREATYPE_DEFAULT)
    return;

  /* Only write if in the right group */
  if (groups && !CheckFlags(group, groups))
    return;

  /* Escape description */
  mystrncpy(escdesc, desc, 100);

  for (c = 0; escdesc[c]; c++)  /* Desc can't contain " */
    if (escdesc[c] == '\"')
      escdesc[c] = '\'';

  switch (format)
  {
    case FORMAT_AREASBBS:
      /* Don't write netmail areas */
      if (areatype != AREATYPE_NETMAIL && areatype != AREATYPE_LOCAL) {
        if (stricmp(msgbase, "MSG") == 0)
          fprintf(fh, "%s %s %s\n", path, tagname, export);
        else if (stricmp(msgbase, "JAM") == 0)
          fprintf(fh, "!%s %s %s\n", path, tagname, export);
        else if (stricmp(msgbase, "") == 0)
          fprintf(fh, "#%s %s %s\n", tagname, tagname, export);
        else
          fprintf(fh, "%s:%s %s %s\n", msgbase, path, tagname, export);
      }
      break;

    case FORMAT_FORWARD:
      /* Don't write netmail, local or BAD areas */
      if (areatype == AREATYPE_ECHOMAIL) {
        if (desc[0])
          fprintf(fh, "%s %s\n", tagname, desc);
        else
          fprintf(fh, "%s\n", tagname);
      }
      break;

    case FORMAT_FORWARDNODESC:
      /* Don't write netmail or BAD areas */
      if (areatype == AREATYPE_ECHOMAIL) {
        fprintf(fh, "%s\n", tagname);
      }
      break;

    case FORMAT_GOLDED:
      /* Don't write pass-through areas */
      if (path[0]) {
        if (stricmp(msgbase, "MSG") == 0)
          gedmsgbase = "FTS1";
        else if (stricmp(msgbase, "JAM") == 0)
          gedmsgbase = "JAM";
        else
          return;

        if (areatype == AREATYPE_NETMAIL)
          gedtype = "NET";
        else if (areatype == AREATYPE_LOCAL)
          gedtype = "LOCAL";
        else
          gedtype = "ECHO";

        if (areatype == AREATYPE_NETMAIL)
          gedflags = "(Loc Pvt)";
        else
          gedflags = "(Loc)";

        if (group)
          sprintf(gedgroupbuf, "%c", group);
        else
          strcpy(gedgroupbuf, "0");

        fprintf(fh, "AREADEF %s \"%s\" %s %s %s %s %s %s\n", tagname, escdesc,
            gedgroupbuf, gedtype, gedmsgbase, path, aka, gedflags);
      }
      break;
  }
}

int main(int argc, char **argv)
{
  FILE *ifh, *ofh;
  uchar sysopname[100], cfgword[30], buf[100];
  uchar *cfgfile = CONFIG_NAME, *outfile=NULL, areafile[100];
  ulong jbcpos;
  time_t t;
  static struct option lopts[] = {
    {"help", 0, NULL, 'h'},
    {"version", 0, NULL, 128},
    {"config", required_argument, NULL, 'c'},
    {"out-file", required_argument, NULL, 'o'},
    {"groups", required_argument, NULL, 'g'},
    {0, 0, 0, 0}
  };
  static uchar optstr[] = "+hc:o:g:";
  static uchar helpstr[] = 
"Usage: crashexport [OPTION]... FORMAT\n"
"Export CrashEcho's configuration to arealist.\n"
"\n"
"  -h, --help            display this help and exit\n"
"      --version         print version number and exit\n"
"  -c, --config=FILE     use this configuration file instead of the default\n"
"  -o, --out-file=FILE   output file\n"
"  -g, --groups=GROUPS   only areas in the specified GROUPS are included\n"
"\n"
"FORMAT can be one of:\n"
"\n"
"  AREASBBS          standard areas.bbs file that can be read by many programs\n"
"  FORWARD           list of areas that can be used for forward-requests on\n"
"                    ther nodes; the file is a pure ASCII file where each line\n"
"                    contains the name of the area and its description\n"
"  FORWARDNODESC     same as FORWARD but without area descriptions\n"
"  GOLDED            area configuration file in GoldED's AREADEF format\n\n";
  int ch, lopt_index;

  while((ch=getopt_long(argc, argv, optstr, lopts, &lopt_index)) != -1){
    switch(ch){
      case 'h':
      case '?':
      default:
        fprintf(stderr, helpstr);
        exit(EXIT_OK);
        /* Not reached */
      case 128:
        fprintf(stderr, "%s\n", verstr);
        exit(EXIT_OK);
        /* Not reached */
      case 'c':
        cfgfile = optarg;
        break;
      case 'o':
        outfile = optarg;
        break;
      case 'g':
        groups = optarg;
        break;
    }
  }

  argc -= optind;
  argv += optind;

  if(argc != 1 || !outfile){
    fprintf(stderr, helpstr);
    exit(EXIT_ERROR);
  }

  if (stricmp(argv[0], "AREASBBS") == 0) {
    format = FORMAT_AREASBBS;
  } else if (stricmp(argv[0], "FORWARD") == 0) {
    format = FORMAT_FORWARD;
  } else if (stricmp(argv[0], "FORWARDNODESC") == 0) {
    format = FORMAT_FORWARDNODESC;
  } else if (stricmp(argv[0], "GOLDED") == 0) {
    format = FORMAT_GOLDED;
  } else {
    fprintf(stderr, "Unknown format \"%s\"\n", argv[0]);
    exit(EXIT_ERROR);
  }

  if (!(cfgbuf = malloc(4000))) {
    fprintf(stderr, "Out of memory\n");
    exit(EXIT_ERROR);
  }

  if (!(ifh = fopen(cfgfile, "rt"))) {
    fprintf(stderr, "Failed to open %s for reading\n", cfgfile);
    fprintf(stderr, "Error: %s", strerror(errno));
    free(cfgbuf);
    exit(EXIT_ERROR);
  }

  if (!(ofh = fopen(outfile, "wt"))) {
    fprintf(stderr, "Failed to open %s for writing\n", (char *) outfile);
    fprintf(stderr, "Error: %s", strerror(errno));
    fclose(ifh);
    free(cfgbuf);
    exit(EXIT_ERROR);
  }

  time(&t);
  fprintf(ofh, "; Generated by %s\n; %s\n", verstr, ctime(&t));

  strcpy(sysopname, "Sysop");
  areafile[0] = 0;

  while (fgets(cfgbuf, 4000, ifh)) {
    jbcpos = 0;
    jbstrcpy(cfgword, cfgbuf, 30, &jbcpos);

    if (stricmp(cfgword, "SYSOP") == 0)
      jbstrcpy(sysopname, cfgbuf, 100, &jbcpos);

    if (stricmp(cfgword, "AREAFILE") == 0)
      jbstrcpy(areafile, cfgbuf, 100, &jbcpos);
  }
  fclose(ifh);

  if (areafile[0] == 0) {
    fprintf(stderr, "AREAFILE not defined in %s\n", (char *) cfgfile);
    fclose(ofh);
    free(cfgbuf);
    exit(EXIT_ERROR);
  }

  if (!(ifh = fopen(areafile, "rt"))) {
    fprintf(stderr, "Failed to open %s for reading\n", (char *) areafile);
    fprintf(stderr, "Error: %s", strerror(errno));
    fclose(ofh);
    free(cfgbuf);
    exit(EXIT_ERROR);
  }

  if (format == FORMAT_AREASBBS)
    fprintf(ofh, "%s ! %s\n", "Default origin", sysopname);

  while (fgets(cfgbuf, 4000, ifh)) {
    jbcpos = 0;
    jbstrcpy(cfgword, cfgbuf, 30, &jbcpos);

    if (stricmp(cfgword, "AREA") == 0 || stricmp(cfgword, "NETMAIL") == 0 || stricmp(cfgword, "LOCALAREA") == 0) {
      if (tagname[0])
        writearea(ofh);

      group = 0;
      unconfirmed = FALSE;

      export[0] = 0;
      desc[0] = 0;

      jbstrcpy(tagname, cfgbuf, 100, &jbcpos);
      jbstrcpy(aka, cfgbuf, 50, &jbcpos);
      jbstrcpy(msgbase, cfgbuf, 10, &jbcpos);
      jbstrcpy(path, cfgbuf, 100, &jbcpos);

      if (stricmp(cfgword, "NETMAIL") == 0)
        areatype = AREATYPE_NETMAIL;

      else if (stricmp(cfgword, "LOCALAREA") == 0)
        areatype = AREATYPE_LOCAL;

      else if (stricmp(tagname, "BAD") == 0)
        areatype = AREATYPE_BAD;

      else if (stricmp(tagname, "DEFAULT") == 0 ||
          strnicmp(tagname, "DEFAULT_", 8) == 0)
        areatype = AREATYPE_DEFAULT;

      else
        areatype = AREATYPE_ECHOMAIL;
    }

    if (stricmp(cfgword, "EXPORT") == 0) {
      struct Node4D tpl4d, tmp4d;

      tpl4d.Zone = 0;
      tpl4d.Net = 0;
      tpl4d.Node = 0;
      tpl4d.Point = 0;

      while (jbstrcpy(buf, cfgbuf, 100, &jbcpos)) {
        if (buf[0] == '!' || buf[0] == '%' || buf[0] == '@')
          strcpy(buf, &buf[1]);

        if (Parse4DTemplate(buf, &tmp4d, &tpl4d)) {
          Copy4D(&tpl4d, &tmp4d);
          tpl4d.Point = 0;

          Print4D(&tmp4d, buf, 100);

          if (strlen(export) < sizeof(export) - 20) {
            if (export[0])
              strcat(export, " ");
            strcat(export, buf);
          }
        }
      }
    }

    if (stricmp(cfgword, "UNCONFIRMED") == 0) {
      unconfirmed = TRUE;
    }

    if (stricmp(cfgword, "DESCRIPTION") == 0) {
      jbstrcpy(desc, cfgbuf, 100, &jbcpos);
    }

    if (stricmp(cfgword, "GROUP") == 0) {
      if (jbstrcpy(buf, cfgbuf, 100, &jbcpos))
        group = buf[0];
    }
  }

  if (tagname[0])
    writearea(ofh);

  fclose(ofh);
  fclose(ifh);
  free(cfgbuf);

  exit(EXIT_OK);
}


syntax highlighted by Code2HTML, v. 0.9.1