/* ================================================================ */ /* Rob Hamerling's MAXIMUS download file scan and sort utility */ /* -> Functions for creating file reports (the mainlines of them). */ /* ================================================================ */ // #define DEBUG_MODE #define INCL_BASE #include #include "downsort.h" #include #include #include #include #include /* ------------------------- */ /* Produce the ORPHAN report */ /* ------------------------- */ void make_orp(dm) struct _filechain **dm; // pointer to file-sort array { static char orp_title[] = " Orphans"; FILE *pf; // file handle char outfile[MAXFN]; // file names USHORT i,j,k; // counters char *strptr; // pointer to a string struct _filechain *ca; // pointer to file-info sprintf(outfile,"%s.%s",lp[P_ORP].name,lp[P_ORP].ext); // build filename if (oper_mode==VERBOSE) printf(MSG_SRT,file_count,area_count,outfile); if (lp[P_ORP].sortflag == ALPHA) // sort on name psort(dm,0,file_count-1,sort_gbl); else if (lp[P_ORP].sortflag == TIMESTAMP) // sort on date psort(dm,0,file_count-1,sort_new); for (i=j=0; ipriv >= HIDDEN) // report "hidden" and up ++j; // count orphans if (j>0) { // yes, there are orphans if (oper_mode == VERBOSE) printf("\n%d Orphans detected",j); // console message pf = fopen(outfile,"w"); // output file if (pf != NULL) { // successful open if (oper_mode == VERBOSE) printf("\nCreating Orphan-report: %s",outfile); for (i=0; ipriv >= HIDDEN) { // report "hidden" and up ca->fdesc = ORPHAN; // assign 'description' k = strsubw(ca->parea->pname,&strptr,52); fprintf(pf,"\n %2.2s %-12.12s %s %-.*s", ca->parea->name, ca->fname, f_date(ca->wdate), k,(k>0)?strptr:""); // (part of) path-name while (k>0) { k = strsubw(strptr+k,&strptr,52); if (k>0) fprintf(pf,"\n%-27.27s%-.*s", "",k,strptr); // remainder of path-name } } } signature(pf,today); // fingerprint fclose(pf); // finished with .ORP file } else // no output possible printf(OPEN_FAIL,outfile); } } /* -------------------------------------------------- */ /* Produce the bulletin format of NEWfiles (BBS-list) */ /* -------------------------------------------------- */ void make_bbs(dm,m,r_priv) struct _filechain **dm; // pointer to file-sort array USHORT m; // maximum file lines int r_priv; // maximum report privilege { FILE *pf,*hf; // file handles char outfile[MAXFN]; // file names char buf[MAXRCD]; // I/O buffer USHORT i,j,k,n; // counters char *strptr; // pointer to a string struct _filechain *ca,*cn; // current and newest file ptr sprintf(outfile,"%s.%s",lp[P_BBS].name,lp[P_BBS].ext); // build filename pf = fopen(outfile,"w"); // output file if (pf != NULL) { // successful open if (oper_mode!=QUIET) printf(MSG_SRT,file_count,area_count,outfile); psort(dm,0,file_count-1,sort_new); n = m; // take maximum files to be listed cn = NULL; // not assigned for (i=j=0; jpriv <= r_priv) { // check file-privilege j++; // presentable file count cn = new_acq(dm[i],cn); // keep pointer to most recent } // within privilege if (n > j) // more req'd than within priv n = j; // new request-limit if (lp[P_BBS].sortflag == ALPHA) { // resort first entries on name if (oper_mode == VERBOSE) printf(MSG_RST,i); // re-sort msg psort(dm,0,i-1,sort_gbl); // sort first 'i' entries } if (oper_mode==VERBOSE) printf(MSG_REC,outfile); strcpy(outfile,PROGNAME); // build headerfilename strcat(outfile,".HDR"); if ((hf = fopen(outfile,"rt")) != NULL) { while (fgets(buf,MAXRCD,hf) != NULL) fputs(buf,pf); fclose(hf); } else printf(MSG_TRL,"Header",outfile); fprintf(pf,"\n%c(%s) %c%u%c most recent of %c%u%c files" " in %c%u%c areas, %c%lu%c MB", O_CYAN,sys_date(today), O_YELLOW,n,O_CYAN, O_YELLOW,file_count,O_CYAN, O_BRIGHT+O_RED,area_count,O_CYAN, O_BRIGHT+O_MAGENTA,(byte_count/1024+512)/1024,O_CYAN); fprintf(pf,"\n%19sDate flag: new on this system since:" " %c = week, %c = month.","",DAYS_7,DAYS_30); if (lp[P_BBS].sortflag == ALPHA && // for filename-sorted list only cn != NULL) { // new file available fprintf(pf,"\n%19sNewest: %c%s %c%8s", "",O_YELLOW,cn->fname, O_GREEN,f_date(cn->wdate)); fprintf(pf," %c(avail: %c%8s)", O_CYAN,O_GREEN,f_date(cn->cdate)); } fprintf(pf,"\n\n%c(Your privilege-level may limit the number " "of files actually shown to you!)%c\n",O_RED,O_CYAN); fprintf(pf,"\n%c%s %c%s %c%s %c%s %c%s\n", O_YELLOW,FN, O_BRIGHT+O_RED,AC, O_MAGENTA,SZ, O_GREEN,DT, O_CYAN,DS); for (i=j=0; jpriv <= r_priv) { // limit to report privilege if (oper_mode==VERBOSE && (j%25)==0) cprintf("\r%5u",j); j++; // list file-count k = strsubw(ca->fdesc,&strptr,47); if (k>0 && lp[P_BBS].wrapflag != WRAP) // default: trunc k = 47; fprintf(pf,"\n%cL%c%c%-12.12s %c%2.2s " "%c%4ldK %c%s%c %c%-.*s", '\20',priv_name[ca->priv-TWIT][0], O_YELLOW,ca->fname, O_RED+O_BRIGHT,ca->parea->name, O_MAGENTA,(ca->size+1023)/1024, // roundup for list only O_GREEN,f_date(ca->wdate), file_age_ind(ca->cdate,ca->ctime), // file age indicator O_CYAN,k,(k>0)?strptr:""); // (part of) description if (lp[P_BBS].wrapflag == WRAP) while (k>0) { k = strsubw(strptr+k,&strptr,47); if (k>0) fprintf(pf,"\n%-32.32s%-.*s", "",k,strptr); // remainder } } } if (oper_mode==VERBOSE) printf("\r%5u",j); signature(pf,today); // fingerprint strcpy(outfile,PROGNAME); // build trailerfilename strcat(outfile,".TRL"); if ((hf = fopen(outfile,"rt")) != NULL) { while (fgets(buf,MAXRCD,hf) != NULL) // copy trailer file fputs(buf,pf); fclose(hf); // close } else printf(MSG_TRL,"Trailer",outfile); fclose(pf); // finished with .BBS file } else // no output possible printf(OPEN_FAIL,outfile); } /* ------------------------------------------------------- */ /* Produce the file-request format of NEWfiles (NEW-list) */ /* ------------------------------------------------------- */ void make_new(dm,m,r_priv) struct _filechain **dm; // pointer to file-sort array USHORT m; // max files to be listed int r_priv; // maximum report privilege { FILE *pf; // file handle char outfile[MAXFN]; // file names USHORT i,j,k,n; // counters char *strptr; // pointer to a string struct _filechain *ca,*cn; // pointer to file-info sprintf(outfile,"%s.%s%c", lp[P_NEW].name,lp[P_NEW].ext,priv_name[r_priv-TWIT][0]); pf = fopen(outfile,"w"); // output file if (pf != NULL) { // opened! if (oper_mode!=QUIET) printf(MSG_SRT,file_count,area_count,outfile); psort(dm,0,file_count-1,sort_new); n = m; // take maximum files to be listed cn = NULL; // no assigned for (i=j=0; jpriv <= r_priv) { // check file-privilege j++; // presentable file count cn = new_acq(dm[i],cn); // keep pointer to most recent } } if (n > j) // more req'd than within priv n = j; // new request-limit if (lp[P_NEW].sortflag == ALPHA) { // resort first entries on name if (oper_mode==VERBOSE) printf(MSG_RST,i); // re-sort msg psort(dm,0,i-1,sort_gbl); // sort first 'i' entries } if (oper_mode==VERBOSE) printf(MSG_REC,outfile); for (i=0; ifname,f_date(cn->wdate)); fprintf(pf," (avail: %8s)",f_date(cn->cdate)); } fprintf(pf,"\n%19sMaximum privilege shown: %s", "",priv_name[r_priv-TWIT]); fprintf(pf,"\n%19sDate flag: new on this system since:" " %c = week, %c = month.","",DAYS_7,DAYS_30); fprintf(pf,"\n\n%s %s %s %s %s",FN,AC,SZ,DT,DS); fprintf(pf,"\n%-.12s ÄÄ %-.5s %-.8s %-.23s%-.24s",HS,HS,HS,HS,HS); for (i=j=0; jpriv <= r_priv) { // only upto max priv_level if (oper_mode==VERBOSE && (j%25)==0) cprintf("\r%5u",j); j++; // file list-count k = strsubw(ca->fdesc,&strptr,47); if (k>0 && lp[P_NEW].wrapflag != WRAP) // default: TRUNC k = 47; fprintf(pf,"\n%-12.12s %2.2s %4ldK %s%c %-.*s", ca->fname, ca->parea->name, (ca->size+1023)/1024, // roundup for list only f_date(ca->wdate), file_age_ind(ca->cdate,ca->ctime), // file age indicator k,(k>0)?strptr:""); // (part of) description if (lp[P_NEW].wrapflag == WRAP) while (k>0) { k = strsubw(strptr+k,&strptr,47); if (k>0) fprintf(pf,"\n%-32.32s%-.*s", "",k,strptr); // remainder } } } if (oper_mode==VERBOSE) printf("\r%5u",j); signature(pf,today); // leave fingerprint for (i=0; ipriv <= r_priv) { // check file-privilege k++; // presentable file count cn = new_acq(dm[i],cn); // keep pointer to most recent } // endif } // endfor if (oper_mode==VERBOSE) printf(MSG_REC,outfile); for (i=0; ifname,f_date(cn->wdate)); fprintf(pf," (avail: %8s)",f_date(cn->cdate)); } fprintf(pf,"\n%19sMaximum privilege shown: %s", "",priv_name[r_priv-TWIT]); fprintf(pf,"\n%19sDate flag: new on this system since:" " %c = week, %c = month.","",DAYS_7,DAYS_30); fprintf(pf,"\n\n%s %s %s %s %s\n",FN,AC,SZ,DT,DS); fprintf(pf,"%-.12s ÄÄ %-.5s %-.8s %-.23s%-.24s",HS,HS,HS,HS,HS); for (i=j=0; ipriv <= r_priv) { // within priv limit if (oper_mode==VERBOSE && (j%25)==0) cprintf("\r%5u",j); j++; k = strsubw(ca->fdesc,&strptr,47); if (k>0 && lp[P_GBL].wrapflag == TRUNC) // default: wrap! k = 47; fprintf(pf,"\n%-12.12s %2.2s %4ldK %s%c %-.*s", ca->fname, ca->parea->name, (ca->size+1023)/1024, // roundup for list only f_date(ca->wdate), file_age_ind(ca->cdate,ca->ctime), // file age indicator k,(k>0)?strptr:""); // (part of) description if (lp[P_GBL].wrapflag != TRUNC) { while (k>0) { k = strsubw(strptr+k,&strptr,47); if (k>0) fprintf(pf,"\n%-32.32s%-.*s", "",k,strptr); // remainder } } } } if (oper_mode==VERBOSE) printf("\r%5u",j); signature(pf,today); // leave fingerprint for (i=0; iparea->name)) { // new area collection strcpy(ac,ca->parea->name); // set new ab_count = 0L; // init area byte count cb = ca; // copy pointer first file cn = NULL; // not assigned for (j=k=0; i+jparea->name); ) { // or at end of area if (cb->priv <= r_priv) { // check file-privilege k++; // presentable file count ab_count += cb->size; // effective area byte count cn = new_acq(cb,cn); // keep pointer to most recent } // endif ++j; // next file-entry if (i+j0) { // any files to list ca->parea->file_count = k; // store it for summary ca->parea->byte_count = ab_count; // store it for summary fprintf(pf,"\n\n\n%-.39s%-.40s",HD,HD); fprintf(pf,"\n%s º %-.60s", strnblk(ac,2,FONT3,LINE1),ca->parea->adesc); fprintf(pf,"\n%s º Available: %u files (%lu.%lu MB)", strnblk(ac,2,FONT3,LINE2),k, (ab_count+52428L)/1048576L, // rounded to 100K ((ab_count+52429L)/104857L)%10); // 100K fraction fprintf(pf,"\n%s º Privilege: %-.9s", strnblk(ac,2,FONT3,LINE3), priv_name[ca->parea->priv-TWIT]); // area privilege fprintf(pf,"\n%s º ",strnblk(ac,2,FONT3,LINE4)); if (cn != NULL) { // newest file fprintf(pf,"Newest: %s %8s ", cn->fname,f_date(cn->wdate)); fprintf(pf," (avail: %8s)",f_date(cn->cdate)); } fprintf(pf,"\n%-.39s%-.40s",HS,HS); fprintf(pf,"\n%s %s %s %s",FN,SZ,DT,DS); fprintf(pf,"\n%-.12s %-.5s %-.8s %-.25s%-.25s",HS,HS,HS,HS,HS); } // endif } // endif if (ca->priv <= r_priv) { // only upto max priv_level if (oper_mode==VERBOSE && (n%25)==0) cprintf("\r%5u",n); // keep SYSOP awake n++; k = strsubw(ca->fdesc,&strptr,50); if (k>0 && lp[P_ALL].wrapflag == TRUNC) // default: wrap k = 50; fprintf(pf,"\n%-12.12s %4ldK %s%c %-.*s", ca->fname, (ca->size+1023)/1024, // round-up for list only f_date(ca->wdate), file_age_ind(ca->cdate,ca->ctime), // file age indicator k,(k>0)?strptr:""); // (part of) description if (lp[P_ALL].wrapflag != TRUNC) while (k>0) { k = strsubw(strptr+k,&strptr,50); if (k>0) fprintf(pf,"\n%-29.29s%-.*s","",k,strptr); // remainder } // endwhile } // endif } // endfor if (oper_mode==VERBOSE) // last value printf("\r%5u",n); // Area Summary report area2 = (struct _downpath *)calloc(area_count,sizeof(struct _downpath)); // dup area-array for sorting! if (area2 == NULL) { // memory not obtained? if (oper_mode!=QUIET) printf("\nNot enough memory for summary report, skipped."); } else { memcpy(area2,area,area_count*sizeof(struct _downpath)); // copy array qsort(area2,area_count,sizeof(struct _downpath),sort_summ); if (oper_mode==VERBOSE) printf("\nWriting Area-Summary"); fprintf(pf,"\n\n\n%-.39s%-.40s\n",HD,HD); for (i=0; iparea->name)) { // new area group if (pf != NULL) { // end of previous group fprintf(pf,"\n"); // extra blank line at end fclose(pf); // finished } strcpy(ac,ca->parea->name); // new area-name c_priv = ca->parea->priv; // new AREA-priv ab_count = 0L; // init area byte count cb = ca; // copy pointer (first file) cn = NULL; // not assigned for (j=k=0; i+jparea->name); ) { // or at end of area if (cb->priv <= r_priv) { // within area privilege ++k; // update included file count ab_count += cb->size; // effective area byte count cn = new_acq(cb,cn); // keep pointer to most recent } // endif ++j; // next file-entry if (i+j 0) { // FIL:path specified strcpy(outfile,filesbbs_path); // copy path strcat(outfile,lp[P_FIL].name); // add filename strcat(outfile,"."); // add separator strncat(outfile,((ac[0]==' ') ? &ac[1] : ac),2); // add ext } else if (strlen(ca->parea->filesbbs) > 0) { // "ListFile" spec strcpy(outfile,ca->parea->filesbbs); strcpy(oldfile,outfile); // backup file for (j=strlen(oldfile), m=1; (j-m)>0 && m<5 && outfile[j-m]!='.'; ++m); // search '.' if (m>=5 || (j-m)<=0) // no extension found: m=0; // concat to end of name strcpy(oldfile+j-m,"."); // add separator strcat(oldfile,BAK); // backup file extension unlink(oldfile); // erase old backup file rename(outfile,oldfile); // rename current to backup } else { // default directory strcpy(outfile,ca->parea->pname); // path to download directory strcat(outfile,lp[P_FIL].name); // add filename strcat(outfile,"."); // add separator strcpy(oldfile,outfile); // backup file strcat(oldfile,BAK); // backup file extension strcat(outfile,lp[P_FIL].ext); // add BBS-extension unlink(oldfile); // erase old backup file rename(outfile,oldfile); // rename current to backup } pf = fopen(outfile,"w"); if (pf != NULL) { fprintf(pf,"\f\n-%s º %-.60s", strnblk(ac,2,FONT3,LINE1),ca->parea->adesc); fprintf(pf,"\n-%s º Available: %u files (%lu.%lu MB)", strnblk(ac,2,FONT3,LINE2),k, (ab_count+52428L)/1048576L, // rounded to 100K ((ab_count+52429L)/104857L)%10); // 100K fraction fprintf(pf,"\n-%s º Privilege: %-.9s", strnblk(ac,2,FONT3,LINE3), priv_name[ca->parea->priv-TWIT]); // area privilege fprintf(pf,"\n-%s º ",strnblk(ac,2,FONT3,LINE4)); if (cn != NULL) { // newest file fprintf(pf,"Newest: %s %8s", cn->fname,f_date(cn->wdate)); fprintf(pf," (avail: %8s)",f_date(cn->cdate)); } fprintf(pf,"\n%-.39s%-.40s",HS,HS); fprintf(pf,"\n%s %s %s %s",FN,SZ,DT,DS); fprintf(pf,"\n%-.12s %-.5s %-.8s %-.25s%-.25s",HS,HS,HS,HS,HS); } else printf(OPEN_FAIL,outfile); } // endif if (pf != NULL) { // check for open file if (ca->priv <= r_priv) { // specified limit if (ca->priv > c_priv) { // higher priv within area c_priv = ca->priv; // set new fprintf(pf,"\n%c%c",'\20',priv_name[ca->priv-TWIT][0]); fprintf(pf,"\n- Following files are classified %s:", priv_name[ca->priv-TWIT]); } fprintf(pf,"\n%s %-s", ca->fname,ca->fdesc); // whole description } // endif } // endif } // endfor if (pf != NULL) { // end of last FILES.BBS fprintf(pf,"\n"); // extra blank line at end fclose(pf); // finished with .ALL file } } // end