home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / dwnsrs59.zip / DOWNRPT3.C < prev    next >
C/C++ Source or Header  |  1993-12-19  |  23KB  |  487 lines

  1.  
  2. /* =============================================================== */
  3. /*  Rob Hamerling's MAXIMUS download file scan and sort utility     */
  4. /*  -> DOWNRPT3.C                                                   */
  5. /*  -> Make SYSOP lists: ORP-list, DUP-list, OK-file, all FILES.BBS */
  6. /* ================================================================ */
  7.  
  8. #define INCL_BASE
  9. #define INCL_NOPMAPI
  10. #include <os2.h>
  11.  
  12. #include <conio.h>
  13. #include <memory.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17.  
  18. #include "..\max\mstruct.h"
  19. #include "downsort.h"
  20. #include "downfpro.h"
  21.  
  22. /* prototypes of local functions */
  23.  
  24. int  filename_cmp(FILECHAIN * _HUGE *, ULONG);
  25. int  dup_ext(char *, char *);
  26.  
  27. /* ------------------------- */
  28. /* Produce the ORPHAN report */
  29. /* ------------------------- */
  30. void make_orp(FILECHAIN * _HUGE *dm,
  31.               DOWNPATH  _HUGE *area,
  32.               LISTPARM  *ls)            /* list specs                    */
  33. {
  34.   FILE   *pf;                           /* file handle                   */
  35.   char   outfile[MAXFN];                /* file names                    */
  36.   ULONG  i,j,fc;                        /* counters                      */
  37.   FILECHAIN *fx;                        /* local pointer to file info    */
  38.  
  39.   sprintf(outfile,"%s.%s",ls->name,ls->ext);  /* build fname */
  40.   if (oper_mode==VERBOSE)
  41.     fprintf(stdout, MSG_SRT, file_total_count, area_total_count, outfile);
  42.   switch(ls->sortflag) {                /* sort                          */
  43.     case ALPHA:     psort(dm,0,file_total_count-1,sort_gbl); break;
  44.     case GROUP:     psort(dm,0,file_total_count-1,sort_all); break;
  45.     case TIMESTAMP: psort(dm,0,file_total_count-1,sort_new); break;
  46.     default: break;
  47.     }
  48.  
  49.   fc = preproc_area(area, dm, ls);      /* files within priv   */
  50.   j = file_total_count - fc;            /* calc orphans */
  51.   if (j>0) {                            /* yes, there are orphans */
  52.     pf = fopen(outfile,WRITE);          /* output file */
  53.     if (pf != NULL) {                   /* successful open */
  54.       if (oper_mode != QUIET)
  55.         fprintf(stdout, MSG_REP, outfile);
  56.       if (oper_mode == VERBOSE)
  57.         fprintf(stdout, MSG_REC);
  58.       block_title(pf, 9, EMPTY, " Orphans ", ls); /* generate block title  */
  59.       fprintf(pf, "\n");
  60.       sep_line(pf, '═', 79, 0);
  61.       fprintf(pf,"  %s   %s       %s    %-s\n", AC, FN, DT, FP);
  62.       sep_line(pf, '─', 8, 12, 9, 47, 0);
  63.       for (i=j=0; i<file_total_count; i++) {
  64.         fx = dm[i];                     /* copy pointer to file info */
  65.         if (fx->priv >= HIDDEN) {       /* report "hidden" and up */
  66.           if (oper_mode==VERBOSE && (j%25)==0) {
  67.             fprintf(stdout, "%6lu\r", j);
  68.             fflush(stdout);
  69.             }
  70.           ++j;                          /* list file-count               */
  71.           fx->fdesc = ORPHAN;           /* assign 'description'          */
  72.           fprintf(pf,"%-8.8s %-12.12s %s%c ",
  73.                       fx->parea->name,
  74.                       fx->fname,
  75.                       f_date(fx->wd.date),
  76.                       file_age_ind(fx));  /*age*/
  77.           desc_part(pf,
  78.                        (fx->fpath==NULL) ? fx->parea->pname :
  79.                                                fx->fpath,
  80.                        47, 47 - ls->desc_indent, ls);
  81.           }
  82.         }
  83.       if (oper_mode==VERBOSE) {
  84.         fprintf(stdout, "%6u\n", j);   /* total reported orphans        */
  85.         fflush(stdout);
  86.         }
  87.       signature(pf,today);              /* fingerprint                   */
  88.       fclose(pf);                       /* finished with .ORP file       */
  89.       }
  90.     else                                /* no output possible            */
  91.       fprintf(stderr, MSG_OPO, outfile, 0);
  92.     }
  93.   }
  94.  
  95. /* ------------------ */
  96. /* Produce a DUP-list */
  97. /* ------------------ */
  98. void make_dup(FILECHAIN * _HUGE *dm,
  99.               LISTPARM  *ls)            /* list specs                    */
  100. {
  101.   FILE   *pf;                           /* file handle                   */
  102.   char   outfile[MAXFN];                /* file names                    */
  103.   ULONG  i,j;                           /* counters                      */
  104.   FILECHAIN *fx;                        /* local pointer to file info    */
  105.  
  106.   sprintf(outfile,"%s.%s", ls->name, ls->ext);
  107.   pf = fopen(outfile,WRITE);            /* output file                   */
  108.   if (pf != NULL) {
  109.     if (oper_mode == VERBOSE)
  110.       fprintf(stdout, MSG_SRT, file_total_count, area_total_count, outfile);
  111.     psort(dm, 0, file_total_count-1, sort_gbl);  /* filename sort        */
  112.     if (oper_mode != QUIET)
  113.       fprintf(stdout, MSG_REP, outfile);
  114.     if (oper_mode == VERBOSE)
  115.       fprintf(stdout, MSG_REC);
  116.     block_title(pf, 12, EMPTY, " Duplicates ", ls);
  117.     if (ls->exclflag != EXCLPRIV)
  118.       fprintf(pf,"\n%s%s\n",
  119.                  MP, priv_name[ls->priv - TWIT]);
  120.     fprintf(pf,"\n%s       %s    %s   %s    %s\n",FN,AC,SZ,DT,FP);
  121.     sep_line(pf, '─', 12, 8, 5, 9, 45, 0);
  122.     for (i=j=0; i<file_total_count; i++) {
  123.       fx = dm[i];                       /* copy pointer to file info */
  124.       if (rpt_coll(fx, ls, TRUE)  &&    /* check if to be listed */
  125.             !filename_cmp(dm, i)) {     /* (pseudo) equal filenames      */
  126.         if (oper_mode==VERBOSE && (j%5)==0) {
  127.           fprintf(stdout, "%6lu\r", j); /* display count by 5            */
  128.           fflush(stdout);
  129.           }
  130.         if (fx->fname[0] != '\0') {  /* not a comment-entry           */
  131.           j++;                          /* count duplicates              */
  132.           fprintf(pf,"%-12.12s %-8.8s %15s ",
  133.                   fx->fname,
  134.                   fx->parea->name,
  135.                   f_size_date(fx));
  136.           desc_part(pf,
  137.                        (fx->fpath==NULL) ? fx->parea->pname :
  138.                                               fx->fpath,
  139.                        41, 41 - ls->desc_indent, ls);
  140.           }
  141.         }
  142.       }
  143.     if (oper_mode==VERBOSE)
  144.       fprintf(stdout, "%6lu\n", j);
  145.     signature(pf,today);                /* leave fingerprint             */
  146.     fclose(pf);                         /* finished with .DUP file       */
  147.     }
  148.   else
  149.     fprintf(stderr, MSG_OPO, outfile, 0);
  150.   }
  151.  
  152. /* ---------------------------------------------- */
  153. /* Compare filename                               */
  154. /* Returns 0 if equal (or to be considered equal) */
  155. /* ---------------------------------------------- */
  156. int  filename_cmp(FILECHAIN * _HUGE *dm,
  157.                   ULONG k)              /* index in dm-array            */
  158. {
  159.   char   f1[9],f2[9];                   /* filenames                    */
  160.   ULONG  i;                             /* index */
  161.   int    rc;                            /* (default) rc */
  162.   FILECHAIN *fx,*fy;                    /* local pointers to file info */
  163.  
  164.   rc = 1;                               /* assume not duplicate */
  165.   fx = dm[k];
  166.   non_wild_init(8, f1, fx->fname);      /* filename of current entry    */
  167.   f1[8] = '\0';                         /* end of string                */
  168.   if (k > 0) {                          /* not very first           */
  169.     i = k-1;                            /* previous entry    */
  170.     fy = dm[i];                         /* copy pointer to file info */
  171.     non_wild_init(8, f2, fy->fname);    /* entry before              */
  172.     f2[8] = '\0';                       /* end of string              */
  173.     if (!stricmp(f1, f2)) {             /* equal filename found */
  174.       rc = 0;                           /* report as 'duplicate' */
  175.       while (!stricmp(f1, f2)) {        /* for all equal filenames */
  176.         if (dup_ext(fx->fname, fy->fname)) {  /* check on (pseudo) unequal */
  177.           return(1);                    /* non-duplicate -> 'unequal' */
  178.           }
  179.         if (i > 0) {                    /* within array bounds */
  180.           --i;                          /* preceding entry */
  181.           fy = dm[i];                   /* copy pointer to file info */
  182.           non_wild_init(8, f2, fy->fname);  /* init */
  183.           f2[8] = '\0';                 /* end of string */
  184.           }
  185.         else                            /* reached head of array */
  186.           break;                        /* escape from while loop */
  187.         }                               /* no more 'before' duplicates */
  188.       }                                 /* maybe any next equal */
  189.     }
  190.   if (k < file_total_count-1) {         /* not very last           */
  191.     i = k+1;                            /* next entry */
  192.     fy = dm[i];                         /* copy pointer to file info */
  193.     non_wild_init(8, f2, fy->fname);    /* entry before              */
  194.     f2[8] = '\0';                       /* end of string              */
  195.     if (!stricmp(f1,f2)) {              /* next filename equal */
  196.       rc = 0;                           /* an equal found */
  197.       while (!stricmp(f1, f2)) {        /* for all equal filenames */
  198.         if (dup_ext(fx->fname, fy->fname)) {  /* check on (pseudo) unequal */
  199.           return(1);                    /* non-duplicate -> unequal */
  200.           }
  201.         if (i < file_total_count-1) {   /* within array bounds */
  202.           ++i;                          /* next consecutive entry */
  203.           fy = dm[i];                   /* copy pointer to file info */
  204.           non_wild_init(8, f2, fy->fname);  /* next entry */
  205.           f2[8] = '\0';                 /* end of string */
  206.           }
  207.         else                            /* reached tail of array */
  208.           break;                        /* escape from while-loop */
  209.         }                               /* no more 'after' duplicates */
  210.       }                                 /* no next equal filename */
  211.     }
  212.   return(rc);                           /* 1 = not any equal filename */
  213.   }
  214.  
  215. /* ----------------------------------------------------- */
  216. /* Test for files to be considered NOT duplicates:       */
  217. /* To be called when filenames are equal if the pair of  */
  218. /* extension is specified in the NON_DUP_EXT table.      */
  219. /* If the pair is in the table the files will not be     */
  220. /* reported as duplicate -> return(1) here.              */
  221. /* Otherwise return(0) -> consider as equal files        */
  222. /* ----------------------------------------------------- */
  223. int  dup_ext(char *f1, char *f2)        /* pointers to filenames        */
  224. {
  225.   char *p1, *p2;                        /* pointers to ext */
  226.   DUPCHAIN *t;                          /* pointer to non-dup ext chain */
  227.  
  228.   p1 = strrchr(f1, '.');                /* offset dot in fn 1 */
  229.   p2 = strrchr(f2, '.');                /* offset dot in fn 2 */
  230.   if (p1!=NULL && p2!=NULL) {           /* both have an extension */
  231.     ++p1; ++p2;                         /* 1st char after dots */
  232.     if (stricmp(p1, p2)) {              /* extensions are not equal */
  233.       t = non_dup_ext;                  /* pointer to chain */
  234.       if (t != NULL) {                  /* any non-dup ext present */
  235.         do {
  236.           if (!stricmp(p1, t->ext1)  &&  /* first equal to first */
  237.               !stricmp(p2, t->ext2))    /* second to second */
  238.             return(1);                  /* considered unequal*/
  239.           else if (!stricmp(p1, t->ext2)  &&  /* first to second */
  240.              !stricmp(p2, t->ext1))     /* second to first */
  241.             return(1);                  /* considered unequal */
  242.           t = t->next;                  /* next element */
  243.           } while (t != NULL);
  244.         }
  245.       }
  246.     }
  247.   return(0);                            /* files (pseudo) equal */
  248.   }
  249.  
  250. /* ---------------------------------------------------------------- */
  251. /* Produce the FILES.BBS files for all area's                       */
  252. /* Sort on name within priv-group, date or as in input FILES.BBS    */
  253. /* Call them FILESBBS.xx  (where 'xx' is a 2-character area-name).  */
  254. /* Put them in the directory indicated by AREA.DAT for 'listfile'.  */
  255. /* ---------------------------------------------------------------- */
  256. void make_fil(FILECHAIN * _HUGE *dm,
  257.               DOWNPATH  _HUGE *area,
  258.               LISTPARM  *ls)
  259. {
  260.   FILE   *pf;                           /* file handle */
  261.   char   outfile[MAXPATH];              /* file spec new FILES.bbs */
  262.   char   oldfile[MAXPATH];              /* file spec old FILES.bbs */
  263.   char   ac[40];                        /* area name */
  264.   ULONG  i;                             /* counters */
  265.   ULONG  akb;                           /* bytecount in KB */
  266.   USHORT j,m;                           /* counter(s) */
  267.   int    c_priv;                        /* privilege */
  268.   FILECHAIN *fx;                        /* local pointer to file info */
  269.  
  270.   if (oper_mode == VERBOSE)
  271.     fprintf(stdout, MSG_SRT, file_total_count, area_total_count,
  272.              "FILES.BBS-files");
  273.  
  274.   switch(ls->sortflag) {
  275.     case ALPHA:
  276.     case GROUP:     psort(dm,0,file_total_count-1,sort_fil);  break;
  277.     case TIMESTAMP: psort(dm,0,file_total_count-1,sort_al2);  break;
  278.     case KEEPSEQ:   psort(dm,0,file_total_count-1,sort_akp);  break;
  279.     default: break;
  280.     }
  281.  
  282.   if (oper_mode != QUIET)
  283.     fprintf(stdout, MSG_REP, "new FILES.BBS files");
  284.   preproc_area(area, dm, ls);           /* count files, bytes  */
  285.  
  286.   pf = NULL;                            /* no file open yet */
  287.   ac[0] = '\0';                         /* init with null-string */
  288.   for (i=0; i<file_total_count; i++) {
  289.     fx = dm[i];                         /* copy pointer */
  290.     if (strcmp(ac, fx->parea->name)) {  /* new area group */
  291.       if (pf != NULL)                   /* end of previous group */
  292.         fclose(pf);                     /* finished */
  293.       strcpy(ac, fx->parea->name);      /* new area */
  294.       c_priv = fx->parea->priv;         /* new AREA-priv */
  295.                                         /* generate new "FILES.BBS" */
  296.       if (strlen(filesbbs_path) > 0) {  /* path parameter specified  */
  297.         strcpy(outfile,filesbbs_path);  /* copy path */
  298.         if (max_aname <= 3) {           /* short areanames */
  299.           strcat(outfile,ls->name);     /* standard filename */
  300.           strcat(outfile,DOT);          /* separator */
  301.           strncat(outfile, ac, 3);      /* extension: 3 chars areaname   */
  302.           }
  303.         else {                          /* long areanames */
  304.           strcat(outfile,ac);           /* filename: areaname */
  305.           strcat(outfile,DOT);          /* separator */
  306.           strcat(outfile, ls->ext);     /* standard extension */
  307.           }
  308.         }
  309.       else if (strlen(fx->parea->filesbbs) > 0) { /* "ListFile" spec */
  310.         strcpy(outfile,fx->parea->filesbbs);
  311.         strcpy(oldfile,outfile);        /* backup file */
  312.         for (j=strlen(oldfile), m=1;
  313.                  (j-m)>0 && m<5 && outfile[j-m]!='.'; ++m); /* search '.'*/
  314.         if (m>=5 || (j-m)<=0)           /* no extension found: */
  315.           m=0;                          /* concat to end of name */
  316.         strcpy(oldfile+j-m,DOT);        /* add separator */
  317.         strcat(oldfile,BAK);            /* backup file extension */
  318.         unlink(oldfile);                /* erase old backup file */
  319.         rename(outfile,oldfile);        /* rename current to backup */
  320.         }
  321.       else {                            /* default directory */
  322.         strcpy(outfile,fx->parea->pname);  /* path to download dir */
  323.         strcat(outfile,ls->name);       /* add filename */
  324.         strcat(outfile,DOT);            /* add separator */
  325.         strcpy(oldfile,outfile);        /* backup file */
  326.         strcat(oldfile,BAK);            /* backup file extension */
  327.         strcat(outfile,ls->ext);        /* add BBS-extension */
  328.         unlink(oldfile);                /* erase old backup file */
  329.         rename(outfile,oldfile);        /* rename current to backup */
  330.         }
  331.  
  332.       if (oper_mode == VERBOSE)         /* progress reporting */
  333.         fprintf(stdout, MSG_REP, outfile);
  334.       else if (oper_mode != QUIET) {
  335.         fprintf(stdout, DOT);
  336.         fflush(stdout);
  337.         }
  338.       pf = fopen(outfile,WRITE);
  339.       if (pf != NULL) {
  340.         akb = (fx->parea->byte_count + 512)/1024;
  341.         if (max_aname <= 3) {           /* short areanames */
  342.           fprintf(pf,"%s\f\n%s%s ║ %-.*s\n",
  343.                     FILPREFX, FILPREFX, strnblk(ac,3,ls->tfont,LINE1),
  344.                     79-3-strlen(strnblk(ac,3,ls->tfont,LINE1)),
  345.                     fx->parea->adesc);
  346.           fprintf(pf,"%s%s ║ Available: %lu files (%lu %cB)\n",
  347.                     FILPREFX,strnblk(ac,3,ls->tfont,LINE2),
  348.                     fx->parea->file_count,         /* area filecount  */
  349.                     (akb < 9999) ? akb : (akb + 512)/1024,
  350.                     (akb < 9999) ? 'K' : 'M');
  351.           fprintf(pf,"%s%s ║",
  352.                       FILPREFX, strnblk(ac,3,ls->tfont,LINE3));
  353.           if (ls->exclflag != EXCLPRIV)
  354.             fprintf(pf," Privilege: %-.9s",
  355.                       priv_name[fx->parea->priv-TWIT]);  /* area priv */
  356.           fprintf(pf,"\n");
  357.           fprintf(pf,"%s%s ║ ",
  358.                       FILPREFX, strnblk(ac,3,ls->tfont,LINE4));
  359.           if (fx->parea->newest != NULL  &&    /* newest file */
  360.               fx->parea->newest->wd.idate != 0) { /* not null-date */
  361.             fprintf(pf,"Newest: %s %8s",
  362.                       fx->parea->newest->fname,
  363.                       f_date(fx->parea->newest->wd.date));
  364.             fprintf(pf," (avail: %8s)",
  365.                       f_date(fx->parea->newest->cd.date));
  366.             }
  367.           fprintf(pf,"\n");
  368.           }
  369.         else {                          /* long areanames */
  370.           fprintf(pf,"%s\f\n", FILPREFX);
  371.           block_title(pf, 8, FILPREFX, ac, ls);
  372.           fprintf(pf,"%s", FILPREFX);  /* start separator line */
  373.           sep_line(pf, '─', 78, 0);
  374.           fprintf(pf,"%s %-.77s\n", FILPREFX, fx->parea->adesc);
  375.           fprintf(pf,"%s Available: %lu files (%lu %cB)\n",
  376.                       FILPREFX, fx->parea->file_count,
  377.                       (akb < 9999) ? akb : (akb + 512)/1024,
  378.                       (akb < 9999) ? 'K' : 'M');
  379.           if (ls->exclflag != EXCLPRIV)
  380.             fprintf(pf,"%s Privilege: %-.9s\n",
  381.                       FILPREFX, priv_name[fx->parea->priv-TWIT]);
  382.           if (fx->parea->newest != NULL  &&     /* newest present */
  383.               fx->parea->newest->wd.idate != 0) { /* not null-date */
  384.             fprintf(pf,"%s Newest: %s %8s",
  385.                       FILPREFX, fx->parea->newest->fname,
  386.                       f_date(fx->parea->newest->wd.date));
  387.             fprintf(pf," (avail: %8s)\n",
  388.                       f_date(fx->parea->newest->cd.date));
  389.             }
  390.           }
  391.         fprintf(pf,"%s", FILPREFX);
  392.         sep_line(pf, '─', 78, 0);
  393.         file_incl(pf, ls);              /* insert user-'logo' */
  394.         fprintf(pf,"%s%s      %s    %s     %s\n%s",
  395.                     FILPREFX, FN, SZ, DT, DS, FILPREFX);
  396.         sep_line(pf, '─', 11, 7, 9, 47, 0);
  397.         }
  398.       else                              /* failed to open new FILES.BBS  */
  399.         fprintf(stderr, MSG_OPO, outfile, 3); /* ??? */
  400.       }                                 /* endif */
  401.     if (pf != NULL) {                   /* check for open file */
  402.       if (fx->priv <= ls->priv) {       /* specified reporting lvl */
  403.         if (fx->priv > c_priv) {        /* higher priv group within area */
  404.           c_priv = fx->priv;            /* set new */
  405.           fprintf(pf,"%c%c\n", '\20',
  406.                      (c_priv>SYSOP) ? 'S' : priv_name[c_priv-TWIT][0]);
  407.           }
  408.         if (fx->fname[0] != '\0') {     /* filename present */
  409.           if (fx->fpath != NULL)        /* explicit pathspec */
  410.             fprintf(pf,"%s%s ", fx->fpath,  /* path */
  411.                                 fx->fname); /* filename */
  412.           else
  413.             fprintf(pf,"%-12.12s", fx->fname); /* filename */
  414.           if (ls->longflag==LONGLIST)   /* 'long' format req'd */
  415.             fprintf(pf,"  %15s",        /* file size + date  */
  416.                         f_size_date(fx));
  417.           if (fx->dl_b==1 || fx->dl_t==1) {  /* download flags */
  418.             fprintf(pf," /");
  419.             if (fx->dl_b==1)            /* free bytes flag */
  420.               fprintf(pf,"b");
  421.             if (fx->dl_t==1)            /* free time flag */
  422.               fprintf(pf,"t");
  423.             }
  424.           fprintf(pf," %-s\n", fx->fdesc);  /* description as 1 piece */
  425.           }
  426.         else if(ls->sortflag == KEEPSEQ)  /* comment, '/K' spec'd  */
  427.           fprintf(pf,"%-s\n", fx->fdesc);
  428.         }
  429.       }
  430.     }
  431.   if (pf != NULL)                       /* end of last FILES.BBS         */
  432.     fclose(pf);                         /* finished with FILES.bbs file  */
  433.   }                                     /* end */
  434.  
  435. /* ------------------------------ */
  436. /* Produce the BinkleyTerm OKFile */
  437. /* (area's in downpath sequence!) */
  438. /* ------------------------------ */
  439. void make_ok(FILECHAIN * _HUGE *dm,
  440.              DOWNPATH  _HUGE *area,
  441.              LISTPARM  *ls)
  442. {
  443.   FILE   *pf;                           /* file handle */
  444.   char   outfile[MAXFN];                /* file names */
  445.   ULONG  i;                             /* file counters */
  446.   USHORT j,k;                           /* area counters */
  447.   FILECHAIN *fx;                        /* local pointer to file info */
  448.  
  449.   sprintf(outfile,"%s.%s%c",
  450.           ls->name,
  451.           ls->ext,
  452.           priv_name[ls->priv-TWIT][0]);
  453.   pf = fopen(outfile,WRITE);            /* output file */
  454.   if (pf != NULL) {
  455.     if (oper_mode != QUIET)
  456.       fprintf(stdout, MSG_REP, outfile);
  457.     file_incl(pf, ls);                  /* insert magic filenames */
  458.     preproc_area(area, dm, ls);         /* count files, bytes */
  459.     if (ls->longflag == LONGLIST) {     /* LONG list requested */
  460.       for (i=0; i<file_total_count; i++) {     /* all files in chain */
  461.         fx = dm[i];                     /* copy file pointer */
  462.         if (rpt_coll(fx, ls, TRUE))     /* check if to be listed */
  463.           fprintf(pf, "@%s %s%s\n",
  464.                       fx->fname,
  465.                       (fx->fpath==NULL) ? fx->parea->pname :
  466.                                               fx->fpath,
  467.                       fx->fname);
  468.         }
  469.       }
  470.     else {                              /* short OK-list requested */
  471.       for (j=k=0; j<area_total_count; j++) { /* all area's in array */
  472.         if (area[j].priv <= ls->priv &&      /* area within privilege*/
  473.             area[j].file_count > 0) {            /* and at least 1 file  */
  474.           if (j<1 || stricmp(area[j].pname,area[k].pname)) { /* not yet */
  475.             fprintf(pf, "%s*.*\n", area[j].pname);
  476.             k = j;                      /* index of last 'printed' */
  477.             }
  478.           }
  479.         }
  480.       }
  481.     fclose(pf);                         /* finished with .ALL file */
  482.     }
  483.   else
  484.     fprintf(stderr, MSG_OPO, outfile, 0);      /* open failed */
  485.   }
  486.  
  487.