/*
 * quick test whipped up to create 3PAKT000.000 in archive from my message
 * base.  this is NOT a good example of how to access XBBS msg bases --
 * I took many potentially lethal shortcuts.  freq XBBSMSG.LZH for a
 * decent API if you're curious.
 * Public domain for all the good it'll do you.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <time.h>
#include "3binary.h"

extern BINDATE3 * fido_2_type3b (char *,BINDATE3 *);  /* 3date.c */

/*-------------------------------------------------------------------------*/
/* XBBS Message header                                                     */
/*-------------------------------------------------------------------------*/
typedef struct {
      char from[36];
      char to[36];
      char subj[64];
      USHORT o_point;
      USHORT length;         /* Length of message */
      ULONG start;           /* Starting postition in text file              */
      char date[20];
      USHORT times;          /* Number of times read                         */
      USHORT dest;           /* Destination node                             */
      USHORT orig;           /* Origination node number                      */
      USHORT cost;           /* Unit cost CHARged to send the message        */
      USHORT orig_net;       /* Origination network number                   */
      USHORT dest_net;       /* Destination network number                   */
      char indate[4];        /* import date  (YMD(null))                     */
      USHORT m_attr;         /* Extra attributes                             */
      USHORT d_zone;         /* Destination zone                             */
      USHORT o_zone;         /* Origination zone                             */
      USHORT attr;           /* Attribute (behavior) of the message          */
      USHORT d_point;
} XMSG;
#define MSGPACKED  0x0200  /* message LZSS compressed   0000 0010 0000 0000*/


size_t stripjnk3 (char *a,size_t len) {

  /*
   * remove some common 'illegal' chars
   * and strip off * Origin lines and tear lines
   */

  register char *p = a,*pp;
  char illegal[] = {'\x8d','\0'};  /* anything you want stripped in illegal */

  while (*p) {
    if(*p == '\t')
      *p = ' ';
    else if ((*p < 31 && *p != '\r') || strchr(illegal,*p)) {
      memmove (p, &p[1], len - ((int) p - (int)a));
      len--;
      if (!len)
        break;
      continue;
    }
    p++;
  }

  p = a;
  while((pp = strstr(p + 1,"\r * Origin: ")) != NULL)
    p = pp;
  if(p && p != a) {
    *p = 0;
    len = strlen(a);
    p--;
    while(p > a && *p == '\r') {
      *p = 0;
      p--;
      len--;
    }
  }
  p = a;
  while((pp = strstr(p + 1,"\r---")) != NULL)
    p = pp;
  if(p && p != a) {
    *p = 0;
    len = strlen(a);
    p--;
    while(p > a && *p == '\r') {
      *p = 0;
      p--;
      len--;
    }
  }

  return len;
}


int main (void) {

  FILE     *handlet,*handled,*phndl = NULL;
  int      x,error = NOERR3;
  long     sized,attrib = 1L,len;
  XMSG     xmsg;
  char    *tbuf,*p,*pp;
  CHUNK3   from,to,prod,area,attr,msgtext,date,id,subj,msg;
  BINDATE3 bdate;
  char     fromt[133],tot[133];
  time_t   seed;

  from.next = &area;
  area.next = &prod;
  prod.next = &attr;
  attr.next = NULL;
  from.data = "Fidonet#1:380/16";
  from.len = strlen(from.data) + sizeof(USHORT);
  from.type = FROM3;
  to.type = TO3;
  prod.data = "3TESTBUT";
  prod.len = strlen(prod.data) + sizeof(USHORT);
  prod.type = PRODUCT3;
  area.data = "NET_DEV";
  area.len = strlen(area.data) + sizeof(USHORT);
  area.type = AREA3;
  attr.len = sizeof(long) + sizeof(USHORT);
  attr.type = ATTRIB3;
  attr.data = &attrib;
  msgtext.type = TEXT3;
  msgtext.next = NULL;
  date.type = DATE3;
  date.len = sizeof(BINDATE3) + sizeof(USHORT);
  date.data = &bdate;
  memset(&bdate,0,sizeof(BINDATE3));
  id.type = ID3;
  id.len = sizeof(long) + sizeof(USHORT);
  id.data = &seed;
  subj.type = SUBJ3;
  msg.data = &len;
  msg.type = MSG3;
  msg.len = sizeof(USHORT) + sizeof(long);

  seed = time(NULL);

  handled = fopen("E:/XBBS2/MSG/XDATA.01b","rb");
  if(handled != NULL) {
    fseek(handled,0L,SEEK_END);
    sized = ftell(handled);
    fseek(handled,0L,SEEK_SET);
    sized /= (long)sizeof(XMSG);  /* how many msgs, but we won't use it */
    tbuf = (char *)malloc(32767);
    if(tbuf) {
      handlet = fopen("E:/XBBS2/MSG/XTEXT.01b","rb"); /* happens to be NET_DEV >;-) */
      if(handlet != NULL) {
        unlink("3PAKT000.000");
        phndl = wopen_pkt3("3PAKT000.000",&from,&error);
        if(error) {
          error3(error);
          goto GotError;
        }

        from.next = &to;
        from.data = fromt;
        to.next = &date;
        to.data = tot;
        date.next = &id;
        id.next = &subj;
        subj.next = &msgtext;

        for(x = 0;x < 25;x++) { /* convert a few messages */
          if(fread(&xmsg,1,sizeof(XMSG),handled) != sizeof(XMSG)) {
            printf("\nMessage data read error\n");
            break;
          }
          if(xmsg.m_attr & MSGPACKED)
            continue; /* ignore compressed msgs -- too much code to include */
          if(fseek(handlet,xmsg.start,SEEK_SET) != 0) {
            printf("\nMessage text seek error\n");
            break;
          }
          if(fread(tbuf,1,xmsg.length,handlet) >= xmsg.length - 1) {

            /* create packet, write header */

            if(!xmsg.o_zone)
              xmsg.o_zone = 1;
            sprintf(fromt,"%s@Fidonet#%u:%u/%u",xmsg.from,xmsg.o_zone,
                    xmsg.orig_net,xmsg.orig);
            if(xmsg.o_point)
              sprintf(&fromt[strlen(fromt)],".%u",xmsg.o_point);
            from.len = strlen(fromt) + sizeof(USHORT);
            seed++;
            strcpy(tot,xmsg.to);
            to.len = strlen(tot) + sizeof(USHORT);
            subj.data = xmsg.subj;
            subj.len = strlen(xmsg.subj) + sizeof(USHORT);
            if(!fido_2_type3b(xmsg.date,&bdate)) {
              printf("\nBad date \"%s\" -- msg skipped.\n",xmsg.date);
              continue;
            }
            tbuf[xmsg.length - 1] = 0;
            p = tbuf;
            while((p = strchr(p,'\01')) != NULL) {  /* strip kludges */
              if((pp = strchr(p,'\r')) != NULL)
                memmove(p,pp + 1,strlen(pp));
              else
                p++;
            }
            msgtext.len = stripjnk3(tbuf,strlen(tbuf)) + sizeof(USHORT);
            msgtext.data = tbuf;

            /* write msg to packet */
            /* (if we had globals, we'd write them first...) */

            if(!write_chunk3_list(phndl,MSG3,&from,&error) || error) {
              error3(error);
              break;
            }

            printf("%d\r",x + 1);
          }
          else {
            printf("\nMessage text read error\n");
            break;
          }
        }

GotError:

        phndl = wclose_pkt3(phndl);
        fclose(handlet);
        free(tbuf);
        fclose(handled);
        printf("\nComplete\n");
      }
      else {
        free(tbuf);
        fclose(handled);
        printf("\nCouldn't open text file\n");
      }
    }
    else {
      fclose(handled);
      printf("\nOut of memory\n");
    }
  }
  else
    printf("\nCouldn't open data file\n");

  return 0;
}
