home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / OFFLINE / QWKTXT46.ZIP / QWKTXT46.C < prev    next >
C/C++ Source or Header  |  1993-12-25  |  14KB  |  467 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <ctype.h>
  4. #include <direct.h>
  5. #include <dos.h>
  6. #include <errno.h>
  7. #include <process.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "qwktxt46.h"
  11.  
  12. void _cdecl main(int argc, char **argv)
  13. {
  14.    FILE *ifp, *ofp;
  15.    int  i = 0, j;
  16.    int  cn, Acc_confs;
  17.    char *sp;
  18.    char stuff[STUFF_SIZE];
  19.    char BBS_name[80];
  20.    char BBS_location[80];
  21.    char BBS_phone_number[25];
  22.    char Packet_date[12];
  23.    char Packet_time[9];
  24.    char User_name[25];
  25.    char temp[25];
  26.    char *unavailable = "Not provided.";
  27.    char fqpname[81];                        /* fully qualified path name    */
  28.  
  29.    TotalMsgsInQWK = 0;
  30.    MsgsPerConference = 0;
  31.  
  32.    printf("%c[2J",27);
  33.    printf("QWK2TXT %s QWK -> TXT converter\n", VERSION);
  34.    printf("Public Domain as of %s\n\n", REL_DATE);
  35.  
  36.    if( (argc != 2)  &&  (argc != 3) )    /* check for proper number of args */
  37.    {
  38.       printf("\n\tusage: qwktxt46 filename.qwk");
  39.       printf("\n\t -or-  qwktxt46 filename.qwk P|U\n\n");
  40.       printf("\n\twhere: filename.qwk is your qwk file");
  41.       printf("\n\t       P = use PKUNZIP.EXE");
  42.       printf("\n\t       U = use UNZIP.EXE\n");
  43.       printf("\n\tNOTE: ONLY one of P or U may be used and if used, the");
  44.       printf("\n\t      filename.qwk MUST be in .ZIP format. P or U is");
  45.       printf("\n\t      not needed if the file is in another archive format.\n\n");
  46.       exit(1);
  47.    }
  48.  
  49.    zipflag = toupper(argv[2][0]);
  50.  
  51.    printf("Decompressing QWK file...One moment, please...\r");
  52.  
  53.    if(mkdir("QWK$TMP") == -1)
  54.    {
  55.       printf("\n\tError: Can't create temporary subdirectory QWK$TMP.");
  56.       exit(1);
  57.    }
  58.  
  59.    arctype = WhichArc(argv[1]);
  60.  
  61.    switch(arctype)
  62.    {
  63.       case -1:
  64.          printf("\n\tFile %s not found.", argv[1]);
  65.          exit(1);
  66.          break;
  67.       case UNKNOWN:
  68.          printf("\n\tArchive method of %s is unknown.", argv[1]);
  69.          exit(1);
  70.          break;
  71.       case ARC:
  72.          chdir("QWK$TMP");
  73.          sprintf(fqpname, "arc x ..\\%s >nul", argv[1]);
  74.          break;
  75.       case ZOO:
  76.          chdir("QWK$TMP");
  77.          sprintf(fqpname, "zoo x ..\\%s >nul", argv[1]);
  78.          break;
  79.       case ARJ:
  80.          chdir("QWK$TMP");
  81.          sprintf(fqpname, "arj x ..\\%s >nul", argv[1]);
  82.          break;
  83.       case LHARC:
  84.          chdir("QWK$TMP");
  85.          sprintf(fqpname, "lharc x ..\\%s >nul", argv[1]);
  86.          break;
  87.       case LHA:
  88.          chdir("QWK$TMP");
  89.          sprintf(fqpname, "lha x ..\\%s >nul", argv[1]);
  90.          break;
  91.       case ZIP:
  92.          chdir("QWK$TMP");
  93.          if(zipflag == 'P')
  94.             sprintf(fqpname, "pkunzip ..\\%s >nul", argv[1]);
  95.          else if(zipflag == 'U')
  96.             sprintf(fqpname, "unzip ..\\%s >nul", argv[1]);
  97.          else
  98.             sprintf(fqpname, "pkunzip ..\\%s >nul", argv[1]);
  99.          break;
  100.    }
  101.  
  102.    system(fqpname);                                  /* decompress the file */
  103.  
  104.    printf("                                              \n\n");
  105.  
  106.    if ((ifp = fopen("control.dat", "r")) == NULL)       /* open control.dat */
  107.    {
  108.       printf("\n\tRequired file CONTROL.DAT not found.");
  109.       exit(1);
  110.    }
  111.  
  112.    if(fgets(stuff,STUFF_SIZE,ifp) != NULL)  /* get BBS' name                */
  113.    {
  114.       strip(stuff);
  115.       strcpy(BBS_name,stuff);
  116.    }
  117.  
  118.    if(fgets(stuff,STUFF_SIZE,ifp) != NULL)  /* get BBS' city/state          */
  119.    {
  120.       strip(stuff);
  121.       if(stuff[0] == 0)
  122.          strcpy(BBS_location,unavailable);
  123.       else
  124.          strcpy(BBS_location,stuff);
  125.    }
  126.  
  127.    if(fgets(stuff,STUFF_SIZE,ifp) != NULL)  /* get BBS' phone number        */ 
  128.    {
  129.       strip(stuff);
  130.       strcpy(BBS_phone_number,stuff);
  131.    }
  132.  
  133.    fgets(stuff, STUFF_SIZE, ifp);        /* toss sysop name into bit-bucket */
  134.    fgets(stuff, STUFF_SIZE, ifp);        /* toss door reg. # and BBS ID too */
  135.  
  136.    if(fgets(stuff,STUFF_SIZE,ifp) != NULL)  /* get packet date & time       */
  137.    {
  138.       strip(stuff);
  139.       strcpy(temp,stuff);
  140.    }
  141.  
  142.    for(i=0; i<10; i++)                     /* strip packet date from string */
  143.       Packet_date[i] = temp[i];
  144.    Packet_date[10] = '\0';
  145.  
  146.    for(i=11; i<19; i++)                    /* strip packet time from string */
  147.       Packet_time[i-11] = temp[i];
  148.    Packet_time[8] = '\0';
  149.  
  150.    if(fgets(stuff,STUFF_SIZE,ifp) != NULL)  /* get user's name              */
  151.    {
  152.       strip(stuff);
  153.       strcpy(User_name,stuff);
  154.    }
  155.  
  156.    for (i=0; i < 3; i++)                  /* Skip over Qmail menu filename, */
  157.       fgets(stuff, STUFF_SIZE, ifp);      /* and two ASCII 0's              */
  158.  
  159.    fgets(stuff, STUFF_SIZE, ifp);                /* get ASCII value of # of */
  160.    strip(stuff);                                 /* conferences available   */
  161.    Acc_confs = atoi(stuff);                      /* and convert it to int   */
  162.  
  163.    cn = i = 0;
  164.    for (;;)                             /* loop to identify all conferences */
  165.    {
  166.       if (!fgets(stuff, STUFF_SIZE, ifp))   
  167.          break;
  168.       strip(stuff);
  169.       if (stuff[0] == 0)
  170.          break;
  171.       if (sscanf(stuff, "%d", &i) != 1)            /* get conference number */
  172.       {                                            /* and convert to an int */
  173.          i = 1;
  174.          break;
  175.       }
  176.       if (!fgets(stuff, STUFF_SIZE, ifp))            /* get conference name */
  177.       {
  178.          printf("\n\tCorrupted conference name in CONTROL.DAT.");
  179.          exit(1);
  180.       }
  181.       strip(stuff);
  182.       confs[cn]._num = i;
  183.       confs[cn]._msgs = 0;
  184.       strcpy(confs[cn++]._name, byp(stuff));
  185.    }
  186.    if ((ofp = fopen("messages.txt", "w")) == NULL)      /* open output file */
  187.    {
  188.       printf("\n\tUnable to open MESSAGES.TXT for output.");
  189.       exit(1);
  190.    }
  191.  
  192.    sep(ofp);                                              /* separate areas */
  193.  
  194.    fprintf(ofp, "        BBS Name: %s\n",   BBS_name);
  195.    fprintf(ofp, "    BBS Location: %s\n",   BBS_location);
  196.    fprintf(ofp, "BBS Phone Number: %s\n",   BBS_phone_number);
  197.    fprintf(ofp, "     Packet Date: %s\n",   Packet_date);
  198.    fprintf(ofp, "     Packet Time: %s\n",   Packet_time);
  199.    fprintf(ofp, "       User Name: %s\n\n", User_name);
  200.  
  201.    fprintf(ofp, "You have access to %d conference%s.\n", Acc_confs,
  202.      (Acc_confs == 1) ? "" : "s");
  203.  
  204.    sep(ofp);                    /* separate info above from actual messages */
  205.  
  206.    printf("Indexing conference: ");  /* read *.NDX files and save that info */
  207.    for (i = 0; i < cn; i++)   
  208.       confs[i]._msgs = nummsg(confs[i]._num);
  209.  
  210.    putchar('\r');
  211.    for(i=0; i < 30; i++)                /* get rid of "Indexing..." message */
  212.       putchar(' ');                     /* (only for aesthetics)            */
  213.  
  214.    fclose(ifp);                    /* finished with CONTROL.DAT so close it */
  215.  
  216.    if ((ifp = fopen("messages.dat", "rb")) == NULL)  /* open message packet */
  217.    {
  218.       printf("Unable to open required file MESSAGES.DAT.");
  219.       fclose(ofp);
  220.       exit(1);
  221.    }
  222.    if (readblk(ifp, stuff))   /* read in 1st record with Sparky's copyright */
  223.    {                          /* abort if we can't read for some reason     */
  224.       printf("\n\tCan't read Sparkware's copyright message in MESSAGES.DAT.");
  225.       fclose(ofp);
  226.       exit(1);
  227.    }
  228.  
  229.    for (i = 0; i < cn; i++)         /* main loop -- do for every conference */
  230.    {
  231.       printf("\rWorking on Conference %d [%s]     ", i, confs[i]._name);
  232.  
  233.       TotalMsgsInQWK += MsgsPerConference;
  234.  
  235.       MsgsPerConference = 0;          /* reset variable for next conference */
  236.  
  237.       while (confs[i]._msgs--)    /* as long as the conference has messages */
  238.       {
  239.          if (readhdr(ifp)) /* read the message header or abort if not found */
  240.          {
  241.             printf("\n\tCan't read message header in MESSAGES.DAT file.");
  242.             printf("\n\t\tConference: %d [%s]", i, confs[i]._name);
  243.             printf("\n\t\t Message #: %d", confs[i]._msgs);
  244.             fclose(ofp);
  245.             exit(1);
  246.          }
  247.                       /* keep user's interest up by displaying useless info */
  248.          fprintf(ofp, "Conference: %s\n", confs[i]._name);
  249.          strncp(stuff, header._msg, 7);
  250.          fprintf(ofp, "Message:    %u\n", atoi(stuff));
  251.          MsgsPerConference += 1;      /* increment conference message count */
  252.          strncp(stuff, header._from, 25);
  253.          strip(stuff);
  254.          fprintf(ofp, "From:       %s\n", stuff);
  255.          strncp(stuff, header._to, 25);
  256.          strip(stuff);
  257.          fprintf(ofp, "To:         %s\t", stuff);
  258.          if( strcmp( stuff, User_name) == 0)
  259.          {
  260.             personal += 1;
  261.             if(header._private == 43)     /* is message private and unread? */
  262.             {                       /* flag message as private and personal */
  263.                fprintf(ofp, "[RECEIVER ONLY]\n");
  264.             }
  265.             else
  266.             {                        /* flag message as public and personal */
  267.                fprintf(ofp, "[PUBLIC]\n");
  268.             }
  269.          }
  270.          else
  271.             fprintf(ofp, "\n");
  272.          strncp(stuff, header._subj, 25);
  273.          strip(stuff);
  274.          fprintf(ofp, "Subject:    %s\n", stuff);
  275.          strncp(stuff, header._pass, 12);
  276.          strip(stuff);
  277.          fprintf(ofp, "Password:   %s\n", stuff);
  278.          strncp(stuff, header._date, 8);
  279.          strncp(&stuff[20], header._time, 5);
  280.          fprintf(ofp, "Date:       %s %s\n\n", stuff, &stuff[20]);
  281.          strncp(stuff, header._count, 6);
  282.          j = atoi(stuff);            /* get # of 128-byte blocks in message */
  283.          while (--j)                                  /* read in each block */
  284.          {
  285.             if (readblk(ifp, stuff))
  286.             {
  287.                fclose(ofp);
  288.                exit(1);
  289.             }
  290.             stuff[128] = 0;
  291.             if (j == 1)
  292.                strip(stuff);
  293.             for (sp = stuff; *sp; sp++)
  294.                if((unsigned char)*sp == 0xE3) /* if π found, output newline */
  295.                   fprintf(ofp, "\n");
  296.                else
  297.                   putc(*sp, ofp);
  298.          }
  299.          sep(ofp);
  300.       }
  301.    }
  302.  
  303.    fclose(ofp);                             /* close text file messages.txt */
  304.    fclose(ifp);                           /* close binary file messages.dat */
  305.  
  306.    printf("\n\nTotal Messages in %s: %u\n", argv[1], TotalMsgsInQWK);
  307.  
  308.  
  309.    system("copy messages.txt .. >nul");
  310.  
  311.    erase(".");                       /* Erase all files in the temporary    */
  312.                                      /*  subdirectory - should work with    */
  313.                                      /*  DOS 3.3 and DOS 5.0 without having */
  314.                                      /*  the query from COMMAND.COM         */
  315.  
  316.    chdir("..");
  317.    rmdir("QWK$TMP");
  318.    exit(0);
  319. }
  320.  
  321. void strip(char *s)              /* strip trailing whitespace from string s */
  322. {
  323.    char *p;
  324.  
  325.    p = s;
  326.    while (*p)
  327.       p++;
  328.    while (p > s && isspace(*--p))
  329.       *p = 0;
  330. }
  331.  
  332. char *byp(char *s)              /* bypass unwanted whitespace from string s */
  333. {
  334.    while (isspace(*s))
  335.       s++;
  336.    return(s);
  337. }
  338.  
  339. int nummsg(int n)                      /* Read Index files and process them */
  340. {
  341.    FILE *ifp;
  342.    int  i, j, ch;
  343.    char name[20];
  344.    char five[5];
  345.  
  346.    sprintf(name, "%03d.ndx", n);
  347.    i = 0;
  348.    if ((ifp = fopen(name, "rb")) != NULL)
  349.    {
  350.       printf("%03d\b\b\b", n);         /* only show conf # if file is found */
  351.  
  352.       for (;;)              /* see how many messages are in this conference */
  353.       {
  354.          for (j = 0; j < 5; j++)
  355.          {
  356.             if ((ch = getc(ifp)) == EOF)
  357.                ch = 26;
  358.             five[j] = ch;
  359.          }
  360.          for (j = 0; j < 5 && five[j] == 26; j++)
  361.             ;
  362.          if (j == 5)
  363.             break;
  364.          i++;
  365.       }
  366.       fclose(ifp);
  367.    }
  368.    return(i);
  369. }
  370.  
  371. int readblk(FILE *fp, char *buff)
  372. {
  373.    int i, ch;
  374.  
  375.    for (i = 0; i < 128; i++)
  376.       if ((ch = getc(fp)) == EOF)
  377.          return(1);
  378.       else
  379.          *buff++ = ch;
  380.    return(0);
  381. }
  382.  
  383. int readhdr(FILE *fp)
  384. {
  385.    if ( fread(&header, 1, sizeof(struct hdr), fp) != sizeof(struct hdr) )
  386.       return(1);
  387.    else
  388.       return(0);
  389. }
  390.  
  391. void strncp(char *d, char *s, int n)       /* this was for the CP/M version */
  392. {
  393.    while (n-- && (*d++ = *s++))
  394.       ;
  395.    *d = 0;
  396. }
  397.  
  398. void sep(FILE *fp)
  399. {
  400.    int i;
  401.  
  402.    putc('\n',fp);
  403.    for (i = 0; i < 70; i++)
  404.       putc('-',fp);
  405.    putc('\n',fp);
  406. }
  407.  
  408. void _cdecl erase(char *pathname)            /* routine to erase temp files */
  409. {
  410.    char tmp[127];
  411.    char pattern[127];
  412.    int  ok;
  413.  
  414.    struct find_t fileinfo;
  415.  
  416.    sprintf(pattern, "%s\\*.*", pathname);
  417.    ok = _dos_findfirst(pattern,0,&fileinfo);
  418.  
  419.    if(ok != 0)
  420.       return;
  421.  
  422.    while(!ok)
  423.    {
  424.       sprintf(tmp, "%s\\%s", pathname, fileinfo.name);
  425.       unlink(tmp);
  426.       ok = _dos_findnext(&fileinfo);
  427.    }
  428. }
  429.  
  430. int WhichArc(char *pName)             /* determines compression method used */
  431. {
  432.    FILE  *afp;
  433.    unsigned char archeader[128];
  434.    int   c, i, n;
  435.  
  436.    memset(archeader, 0, sizeof(archeader));
  437.    afp = fopen(pName, "rb");
  438.    if (afp == NULL) return -1;
  439.    n = fread(archeader, sizeof(unsigned char), sizeof(archeader) - sizeof(unsigned char), afp);
  440.    fclose(afp);
  441.  
  442.    if (n <= 0) return -1;
  443.  
  444.    if (n >= 7 && n >= archeader[0] + 2)
  445.    {
  446.       for (c = 0, i = archeader[0]; i--; c += (archeader+2)[i]);
  447.       if ((c & 0x00FF) == archeader[1] &&
  448.           archeader[2] == '-'          &&
  449.           archeader[3] == 'l'          &&
  450.           archeader[4] == 'h'          &&
  451.           archeader[6] == '-') return (archeader[5] > '1') ? LHA : LHARC;
  452.    }
  453.  
  454.    if (n >= 2)
  455.    {
  456.       if (archeader[0] == 0x60 && archeader[1] == 0xEA) return ARJ;
  457.       if (archeader[0] == 'P'  && archeader[1] == 'K')  return ZIP;
  458.    }
  459.  
  460.    if (n >= 3
  461.       && archeader[0] == 'Z' && archeader[1] == 'O' && archeader[2] == 'O') return ZOO;
  462.  
  463.    if (n >= 25 && archeader[0] == 0x1A) return ARC;
  464.  
  465.    return UNKNOWN;
  466. }
  467.