% file: ctan_chk.w % \def\Tex{\TeX} \def\cweb{\Cweb} \def\Cweb{{\prgstyle Cweb}} \def\prgstyle{\tt \sl } \def\NOsign{ {\tt{\char`\#}} } \def\Verticalbar{{\tt \char`|}} \def\GTsign{ \ifmmode > \else $>$ \fi } \def\Arrow{$\Rightarrow$} \def\prtobrace{$\{$} \def\prtcbrace{$\}$} \def\Backslash{ {\tt\char`\\} } \def\printlistinglineno{\hskip .7 in \llap{\the\lineno:\quad}} \def\ptindent#1{\line{\hskip.5in{#1}\hfill}} \def\Yacco2{Ya$c_2o_2$} \def\yacco2{\Yacco2} \def\O2{$O_2$} \def\o2{\O2} \def\Cpp{C\kern-.25em \raise.25ex\hbox{\tt $+\kern-0.2ex+$}} \def\Olinker{$O_{2}^{linker}$} \def\olinker{$O_{2}^{linker}$} \def\TILDE{\catcode`\~=11{}~} \def\INDENT#1#2{\line{\hskip#1{#2}\hfill}} \def\fbreak{\hfill\break} @* Gawk program |ctan_chk.gawk|.\fbreak Basic Gawk program that uses Ctan's published guidelines for authors to help eliminate slopiness in uploaded files/project. It is completely open for users to program additional guidelines and Ctan's future adjustments. The program came about when I first attempted to upload ``Yacco2'' for Ctan consideration. As Yacco2 was quite large, it took me 3 attempts to clean up my project. Depending on how u develop your project, in my case the Yacco2 project for Ctan upload is a subset of the complete system and so each uplift required the guideline assessment/purging process. This is my attempt to help both the author in getting the new system in shape for Ctan uplift and to lower the Ctan volanteers interaction to aid for publishing on their servers. It is my thank you to these volanteers / Ctan. \fbreak \fbreak This |gawk| program verifies whether an upload project for CTAN follows its published guidelines on their website:\fbreak \ptindent{http://ctan.org/upload/} \fbreak Here is the link to the awk/gawk reference manual for people needing a refresher to its programming statements:\fbreak \ptindent{https://www.gnu.org/software/gawk/manual/gawk.html\#Reading-Files} @*1 License.\fbreak ctan\_chk's distributed source code is subject to the terms of the GNU General Public License (version 3). If a copy of the MPL was not distributed with this file, you can obtain one at https://gnu.org/licenses/gpl.html. \fbreak \fbreak \ptindent{Project: ctan guidelines verifier and corrector program for uploading projects} \ptindent{Distributed under license: GNU General Public License (version 3).} \ptindent{Distribution Date: \today} \ptindent{Distribution version: 1.0} \ptindent{Comments: Currently for the Unix flavoured Platforms running Gawk} \ptindent{Author: Dave Bone} \fbreak \ptindent{Contributors list:} \ptindent{ Dave Bone} @*2 |Ctan_chk| reference.\fbreak Unzip the |ctan_chk.zip| file. Please read |ctan_chk.pdf| document. It instructs one in ``how to'' use the gawk |ctan_chk.gawk| program. @*2 Literate Programming genre.\fbreak |ctan_chk.pdf| user manual and |ctan_chk.gawk| program are generated by the Cweb system's {\it{cweave}} and {\it{ctangle}} programs along with the {\it{pdftex}}. The |ctan_chk_bash| script does it all for u; have a read it doesn't bite. Please consider using Cweb and joining ``www.tug.org'' where u'll find the Cweb system. @*1 Comments on program's functions.\fbreak Normally u edit the |ctan_chk.gawk| file (using gawk comments) as to what "verification function" is called to check out your project's files. Here is a list of the verification functions to call:\fbreak Helper functions:\fbreak \ptindent{|is_file_a_directory| --- is file a directory type rather than a data type?} \ptindent{|is_file_an_executable| --- Maybe too platform dependent: is it an executable} \fbreak Verification functions:\fbreak \ptindent{|chk_auxiliary_files| --- files that should be removed / deleted} \ptindent{|chk_file_permissions| --- file execute permissions check} \ptindent{|chk_extended_file_attributes| --- does file have extended attribute like @@} \ptindent{|chk_empty_files| --- zero byte size file?} \ptindent{|chk_empty_directory| --- empty folder} \ptindent{|chk_file_to_bypass_in_zip| --- file to bypass by zip using its -x option} \fbreak Correction functions:\fbreak \ptindent{|remove_file_s_execute_attribute| --- Read ``Remove file's execute attribute'' section for details} \ptindent{|delete_file| --- interacts with user. Used by itself or from other functions like |chk_auxiliary_files|} \ptindent{|remove_file_s_extended_attributes| --- Remove extended attribute from file (platform dependent)} @*2 Running Gawk program has 2 run/pass attitude.\fbreak U run this program twice with appropriate editing sessions inbetween the run passes:\fbreak \ptindent{run Pass 1 function where your edited functions to call and capturing output with {\it{tee}} utility} \ptindent{\Arrow{} pass 1's input file is an absolute pathed files list. See |How to use this gawk program| section} \ptindent{\Arrow{} assess the messages outputted as to what guidelines need to be corrected} \ptindent{\Arrow{} outputted messages have 2 parts: part 1 the filename and part 2 the quoted message} \fbreak \ptindent{run Pass 2 function where u comment out pass 1 call and uncomment pass 2 function call} \ptindent{\Arrow{} inside the |pass2_correct| function, uncomment the appropriate correction function to call} \ptindent{\Arrow{} the captured messages from {\it{tee}} of pass 1 is its inputted file} \ptindent{\Arrow{} in awk/gawk terms this |gawk|'s record is composed of fields where the field separator is space} \ptindent{\Arrow{} so the 2nd pass receives the 2 fields filename, and message} \fbreak \fbreak Output example of guideline violations from Pass 1:\fbreak \ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'} \ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'} \ptindent{\Arrow{} "/yacco2/.DS\_Store" 'Bypass file in zip'} \ptindent{\Arrow{} "/yacco2/.gitignore" 'Auxilary file to be deleted'} \ptindent{\Arrow{} "/yacco2/.nbattrs" 'Extended attributes -rwxr-xr-x+'} \ptindent{\Arrow{} "/yacco2/.nbattrs" 'Write permissions -rwxr-xr-x+ to possibly delete file type: XML'} \ptindent{\Arrow{} "/yacco2/.nbattrs" 'Bypass file in zip'} \ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Extended attributes -rwxr-xr-x@@'} \ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: data'} \ptindent{\Arrow{} "/yacco2/bin/.DS\_Store" 'Bypass file in zip'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Empty file to be deleted'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Auxilary file to be deleted'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrtracings.log" 'Empty file to be deleted'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/o2.man" 'Extended attributes -rw-r--r--@@'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/o2linker.man" 'Extended attributes -rw-r--r--@@'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2.man" 'Extended attributes -rw-r--r--@@'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Auxilary file to be deleted'} \ptindent{\Arrow{} "/yacco2/bin/man/man1/yacco2cmd.tmp" 'Empty file to be deleted'} \ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Extended attributes -rwxr-xr-x@@'} \ptindent{\Arrow{} "/yacco2/bld\_bash\_APPLE" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: ASCII'} \ptindent{\Arrow{} "/yacco2/book/appendix\_a.aux" 'Auxilary file to be deleted'} \ptindent{\Arrow{} "/yacco2/book/ch\_fsm.tex" 'Write permissions -rwxr-xr-x@@ to possibly delete file type: LaTeX'} \fbreak Running the initial program could potentially output the above sampling. If there are just 1 message type outputted then u would just focus on ``pass 2'' to correct it. Having a mix of messages means ``pass 1'' should be edited to just deal with the 1 message type at a time. This allows the homogenous output to be captured and edit the removal of files to bypass. Now the program can be edited to support the message type action correcting the violation and rerun. Each listed guideline type would go thru this edit behaviour: ``pass 1'' to see the violations, analyse its outcome, re-edit program, and then run the correction. @*2 Anatomy of this |gawk| program.\fbreak It contains 3 |gawk| actions: BEGIN, Body, and END. This program's BEGIN and END actions are just read record stats. U can add your own code as this program is open to your creativity. The action Body contains the 2 passes: |pass1_guidelines_verify| and |pass2_correct|. To comment out a function call, add a \NOsign{} at the beginning of its line. To activate a commented out function call, just remove its |gawk|'s comment character: \NOsign. @*2 How to generate the pdf document and this gawk program.\fbreak The \Cweb{} ``literate programming'' framework is used to generate its pdf document and its gawk program from |ctan_chk.w|. Though Cweb emits a ``c'' type code, gawk code is very similar to ``c''.\fbreak 0) Run from a terminal using bash.\fbreak \ptindent{{\bf{. ctan\_chk\_bash}}} \ptindent{\Arrow{} The various utilities used are outputed on the terminal} U are open to add your own code to the |ctan_chk.w| program and rerun the above script. If u do not have the \Cweb{} framework installed, u can add the code to the |ctan_chk.gawk| file. @*2 How to use this gawk program.\fbreak 0) Run from a terminal using bash.\fbreak 1) Generate a file containing your project's files whose path is absolute\fbreak \ptindent{{\bf{find /absolute path of your project \GTsign{} xxx}}} \ptindent{\Arrow{} xxx is a holding file containing your project's files} \ptindent{\Arrow{} example of an absolute path: {\bf {/usr/local/yacco2}}} 2) Edit |ctan_chk.gawk| to what function calls u want to use inside |pass1_guidelines_verify|\fbreak 3) Run gawk ctan\_chk program verifying your project\fbreak \ptindent{{\bf{gawk -f ctan\_chk.gawk xxx}} \NOsign xxx is the file read containing the files to assess}\fbreak \ptindent{\Arrow{} it outputs files to correct on the terminal with appropriate guideline message} \ptindent{\Arrow{} no outputted messages means your project passed with flying colours :\prtcbrace} \fbreak \ptindent{\Arrow{} To capture the verification output:} \ptindent{{\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}}}\fbreak \ptindent{\Arrow{} Use of {\it{tee}} utility to capture the output into yyy file} @*3 Example: Checking auxilary files to delete.\fbreak Here are the steps to see whether there are files to remove/delete. File xxx contains the files to verify as exampled earlier in this document.\fbreak 1) {\bf{gawk -f ctan\_chk.gawk xxx}}\fbreak \fbreak 2) Its output should have messages similar to this:\fbreak \ptindent{\Arrow{} "/yacco2/bin/man/man1/1lrerrors.log" 'Auxilary file to be deleted'} \fbreak 3) Rerun {\bf{gawk -f ctan\_chk.gawk xxx\Verticalbar{}tee yyy}} where the output messages are put in {\bf{yyy}} file.\fbreak \break 4) Edit: comment out pass1\_guidelines\_verify and uncomment \#pass2\_correct in Body action code:\fbreak The gened |ctan_chk.gawk| program could have different commented ``section no:'' used in the below edit session. What is important are function names referenced: for example, |pass1_guidelines_verify| which you'll find in your |ctan_chk.gawk| program. Same comments apply against the other pieces of code being edited.\fbreak \ptindent{\# section no:22*/} \ptindent{\# section no28:*/} \ptindent{\prtobrace} \ptindent{ pass1\_guidelines\_verify(\$1);} \ptindent{ \#pass2\_correct(\$1,\$2);} \ptindent{\prtcbrace} to\fbreak \ptindent{\# section no:22*/} \ptindent{\# section no28:*/} \ptindent{\prtobrace} \ptindent{ \#pass1\_guidelines\_verify(\$1);} \ptindent{ pass2\_correct(\$1,\$2);} \ptindent{\prtcbrace} \fbreak 5) Edit: uncomment out \#delete\_file in pass2\_correct:\fbreak \ptindent{\# section no:28*/} \ptindent{\# section no29:*/} \ptindent{function pass2\_correct(filename,message)} \ptindent{\prtobrace} \ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);} \ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);} \ptindent{ \#delete\_file(filename);} \ptindent{\prtcbrace} to\break \ptindent{\# section no:28*/} \ptindent{\# section no29:*/} \ptindent{function pass2\_correct(filename,message)} \ptindent{\prtobrace} \ptindent{ \#remove\_file\_s\_execute\_attribute(filename,message);} \ptindent{ \#remove\_file\_s\_extended\_attributes(filename,message);} \ptindent{ delete\_file(filename);} \ptindent{\prtcbrace} \fbreak \fbreak \fbreak \fbreak \fbreak \fbreak 6) Save edited |ctan_chk.gawk| program and rerun with {\bf{yyy}}:\fbreak \ptindent{\Arrow{} {\bf {gawk -f ctan\_chk.gawk yyy}}} Each file being deleted is questioned and allows u to bypass it.\fbreak This is due to the {\bf{-i}} option used in {\it{rm -i file-to-delete}}\fbreak \fbreak Other guideline contraints would follow the same run / edit / rerun template above adjusting the program accordingly.\fbreak \ptindent{\Arrow{} {\bf{Just remember to reset the program back to its initial setting.}}} As an aside comment, u could have uncommented the |delete_file| call inside the |chk_auxiliary_files| function and do the correction while in the ``assess guideline'' pass. So why did u not express this before :\prtobrace? Well the normal correction pattern is see what guidelines are violated by ``pass 1', edit the program, and then rerun against ``pass 2'' correction. Once u are familiar with the program throw out my patterns and jig your own :\prtcbrace. @* Function code sections. @*2 ctan gawk's comments --- author, license etc. @= # # Program: ctan_chk.gawk # # Author: Dave Bone # # License: # This Source Code Form is subject to the terms of the GNU General Public License (version 3). # If a copy of the MPL was not distributed with this file, # You can obtain one at: "https://gnu.org/licenses/gpl.html". # # Purpose: Implementation of some suggested CTAN guidelines that an upload project should respect. # Correction functions help u cleanup the droppings. # See www.ctan.org website for "upload guideline" document # Read ctan_chk.pdf document describing the program with various run scenarios. # # @*1 Helper functions. @*2 Is file a directory.\fbreak Directory found returns 1. @<|is_file_a_directory|@>= function is_file_a_directory(filename, filetype)@\ { x="file \"%s\""; y=sprintf(x,filename); y|getline a; close(y); split(a,parts); filetype[1] = parts[2]; xx = parts[2]; str= "^directory$"; if (xx ~ str) { return 1; } return 0; } @*2 Is file an executable.\fbreak This function {\bf{might be too platform dependent}}.\fbreak If so then don't call it or find an alternative.\fbreak A return 1 means it's an executable. @<|is_file_an_executable|@>= function is_file_an_executable(filename, filetype)@\ { x="file %s"; y=sprintf(x,filename); y|getline a; close(y); split(a,parts); filetype[1] = parts[2]; xx = parts[2]; str= "(executable|POSIX|Mach-O|ELF)$"; if (xx ~ str) { return 1; } return 0; } @*1 Guideline assessment functions. @*2 Check for auxiliary type files.\fbreak ``str'' contains a regular expression of file extensions to search for starting with a ``.'' followed by the round bracket expression of extensions to search on ending by the end-of-string regular expression indicator: \$. Inside the rounded bracket expression is the choice of extensions separated by \Verticalbar{} which is the ``or'' operator of a regular expression.\fbreak \fbreak The double \Backslash{} in str is due to how gawk parses the program code: it does a double pass:\fbreak \ptindent{1) on the string: str} \ptindent{2) on the regular expression called} Just having a ``.'' at the start of regular expression means it is a single ``wild character'' to accept. To accept a period ``.'' that starts the file extension, u have to escape it. Pass 1 for the literal string is the first escape sequence on \Backslash{} the 2nd backslash. In pass 2 for the regular expession called, the \Backslash{} escapes the ``.'' to not interpret as the regular expression wild character.\fbreak \fbreak str can be added to. Make sure u include the added extension started with the \Verticalbar{} when appended to before the closing off rounded bracked ``)''. \fbreak \fbreak |chk_auxiliary_files| outputs a 2 part message: file name and message it considers as an auxiliary file to be deleted. Calling |delete_file| interacts with the user whether to delete it or not. It is commented out so that the messages can saved and reviewed before the correction pass takes place: See |Pass 2 --- correct violated guidelines| section providing more information. U can uncomment the |delete_file| statement below if u prefer to delete the file in the assessment pass rather than the correction pass. Your call and temperment. @<|chk_auxiliary_files|@>= function chk_auxiliary_files(filename)@\ { if (is_file_a_directory(filename) == 1) return 0; str= "\\.(ps|gitignore|git|aux|log|bbl|bcf|blg|brf|ilg|ind|idx|glo|loa|lof|lot|nav|out|snm|vrb|toc|dvi|glg|gls|tmp|o|bak|mpx|scn|toc)$"; if (filename ~ str) { a= "\"%s\" 'Auxilary file to be deleted'"; b= sprintf(a,filename); print b; #delete_file(filename); return 1; } return 0; } @*2 Check for extended attributes.\fbreak Basicly looks at the output from the ``ls -al'' of a file. If there are extended attributes it will be displayed at the end of the first field as ``@@'' or ``+''. It outputs the filename and message to the terminal. Return 1 if found. @<|chk_extended_file_attributes|@>= function chk_extended_file_attributes(filename)@\ { x="ls -al \"%s\""; y=sprintf(x,filename); y|getline a; close(y); number_of_fields = split(a,parts); if (number_of_fields < 9) return 0; xx=parts[1]; str= "(@@|+)$"; if (xx !~ str) { return 0; } a="\"%s\" 'Extended attributes %s'"; b=sprintf(a,filename,parts[1]); print b; #remove_file_s_extended_attributes(filename,b); return 1; } @*2 Check for empty files.\fbreak Uncomment out the |delete_file| statement below if u want to remove it in the assessment phase. Asks whether to delete the zero sized file and returns 1. @<|chk_empty_files|@>= function chk_empty_files(filename)@\ { if (is_file_a_directory(filename) == 1) return 0; x="ls -al \"%s\""; y=sprintf(x,filename); y|getline a; close(y); number_of_fields = split(a,parts); if (number_of_fields < 9)@\ { print "ERROR ===> ls -al should be 9 fields and it isn't: " a " no fields: " number_of_fields; return 0; } i=strtonum(parts[5]); if (i > 0){ return 0; } a="\"%s\" 'Empty file to be deleted'"; b=sprintf(a,filename); print b; #delete_file(filename); return 1; } @*2 Check for empty directory.\fbreak Empty directory found returns a 1.\fbreak This check requires u to assess what u want to do: delete it, or add an ``info.txt'' file inside it. For example in the ``Yacco2'' project, it is a full development framework of a compiler/compile, and its API library. It has empty Debug folders. Its Release folders contained content. Depending on what the user wanted to debug and link against, the empty Debug folder provided consistency to the framework and hence it was needed. So an ``info.txt'' file was created inside each Debug folder expressing their intent/use to the developer. @<|chk_empty_directory|@>= function chk_empty_directory(filename)@\ { if (is_file_a_directory(filename) == 0) return 0; x="du -sk \"%s\""; y=sprintf(x,filename); y|getline a; close(y); number_of_fields = split(a,parts); i=strtonum(parts[1]); if (i > 0) return 0; a="\"%s\" 'Empty directory to be deleted or needs to add info.txt file inside it'"; b=sprintf(a,filename); print b; return 1; } @*2 Check file permissions.\fbreak Bypass a directory. If the file does not have an executable attribute then exit stage gracefully. @<|chk_file_permissions|@>= function chk_file_permissions(filename)@\ { filetype[1]=""; if (is_file_a_directory(filename, filetype) == 1) return 0; if (is_file_an_executable(filename,filetype) == 1) return 0; x="ls -al \"%s\""; y=sprintf(x,filename); y|getline a; close(y); number_fields = split(a,parts); str= "x"; if (parts[1] ~ str) { a="\"%s\" 'Write permissions %s to possibly delete file type: %s'"; b=sprintf(a,filename,parts[1],filetype[1]); print b; return 1; } return 0; } @*2 Check file to bypass in zip.\fbreak This is just a check function that lists files to bypass in the zip file creation process.\fbreak An example of creating a zip file:\fbreak \ptindent{{\bf{zip -r -ll yacco2.zip yacco2 -x '*DS\_Store' -x '*.nbattrs'}}} \ptindent{\Arrow{} -r recurse through the folder getting all its subfolders and their contents} \ptindent{\Arrow{} -ll parameter reduces carriage return/line feed combo to line feed} \ptindent{\Arrow{} -x parameter lists by regular expression the file(s) to bypass} \ptindent{\Arrow{} The bypassed exampled files are Apple OSX specific} @<|chk_file_to_bypass_in_zip|@>= function chk_file_to_bypass_in_zip(filename) { str= ".(DS_Store|.nbattrs)$"; if (filename ~ str) { a="\"%s\" 'Bypass file in zip'"; b=sprintf(a,filename); print b; return 1; } return 0; } @*1 Correct guideline violations. @*2 Remove file's execute attribute.\fbreak Due to security reasons, u cannot have an indirect bash script run against a list of files to change their ownership attributes. It will run but nothing will be changed.\fbreak So what to do?\fbreak \ptindent{\Arrow{} gawk -f |ctan_chk.gawk| xxx \Verticalbar{}tee yyy} \ptindent{\Arrow{} \ \ \ \ u can use your own temporary file name instead of yyy} \ptindent{\Arrow{} \ \ \ \ just remember to substitute your file name in place of yyy} \ptindent{\Arrow{} where the |chk_file_permissions| function is the only function run} \ptindent{\Arrow{} and the other functions have been commented out} \fbreak \ptindent{Edit yyy file containing the list of potential files, removing files keeping their execute attribute.} \break \ptindent{Run this below gawk script interactively from your bash terminal} \ptindent{\Arrow{} This means copy the below script line and paste it in the bash terminal} \ptindent{\ \ \ \ \ gawk '\prtobrace x="chmod a-x \%s;";y=sprint(x,\$1);system(y);\prtcbrace' yyy} \fbreak Some comments on the above interactive |gawk| program:\fbreak 1) It reads the yyy file where each line read contains 2 fields: filename, and message separated by a space\fbreak 2) It runs the {\it{chmod}} utility by the {\bf{system}} statement\fbreak 3) Not sure about {\bf{chmod}} utility, do a ``man chmod'' on your bash terminal for more information\fbreak 4) If u boobooed on a file and removed the execute attribute, here is a correction:\fbreak \ptindent{\Arrow{} {\bf{chmod a+x file-to-reimplement}}} @<|remove_file_s_execute_attribute|@>= function remove_file_s_execute_attribute(filename, message)@\ { print "Please read |ctan_chk.pdf| to find instructions on how remove execute attribute from a file"; } @*2 Remove file's with extended attributes.\fbreak This function is platform dependent. The {\it{xattr}} is the utility to run on Apple's OSx platform to remove the extension. @<|remove_file_s_extended_attributes|@>= function remove_file_s_extended_attributes(filename, message)@\ { x="echo %s\";xattr -c %s"; y=sprintf(x,message,filename); print y; #y|getline a; #close(y); } @*2 Delete file.\fbreak The file name passed to it is displayed and asks whether it should be deleted. @<|delete_file|@>= function delete_file(filename)@\ { x="rm -i \"%s\""; y=sprintf(x,filename); y|getline a; close(y); } @* Pass 1 / 2 guidelines assessment and correction.\fbreak @*2 Pass 1 --- guidelines assessment.\fbreak Using a text editor (un)comment out the appropriate function calls in |ctan_chk.gawk| that u'd like to verify. For example checking just the files to be deleted, comment out all the below functions except |chk_auxiliary_files|. U can run pass 1 as is to see whether any of your files for upload do not pass the guidelines. From there u can adjust what function to deal with by commenting out the others fuctions and teeing out its found infidelities for pass 2 correction. @= function pass1_guidelines_verify(filename) { chk_auxiliary_files(filename); chk_extended_file_attributes(filename); chk_empty_files(filename); chk_empty_directory(filename); chk_file_permissions(filename); chk_file_to_bypass_in_zip(filename); } @*2 Pass 2 --- correct violated guidelines.\fbreak There are 3 functions whereby 2 of them do usefull things.\fbreak \ptindent{|delete_file| function asks whether its passed file should be deleted} \ptindent{\Arrow{} Remove the -i in {\bf{rm -i}} statement if u don't want the interactive question} \fbreak \ptindent{|remove_file_s_extended_attributes| function is tailored to the Apple platform} \ptindent{\Arrow{} Other platforms should have an equivalent {\it{xattr -c}} utility} \ptindent{\Arrow{} {\bf{Caveat:}} know what utility to use and adjust accordingly to remove the extension attribute} \ptindent{\Arrow{} Have a read at https://en.wikipedia.org/wiki/Extended\_file\_attributes\#cite\_note-14} \fbreak \ptindent{|remove_file_s_execute_attribute| tells u to read the {\bf{ctan\_chk.pdf}} document} \ptindent{\Arrow{} on ``how to remove'' the execute attribute from a file} \fbreak Uncomment the appropriate below function to call. And comment out |pass1_guidelines_verify| statement, and uncomment |pass2_correct| statement in |Body| action before reruning this program. @= function pass2_correct(filename, message) { #remove_file_s_execute_attribute(filename,message); #remove_file_s_extended_attributes(filename,message); #delete_file(filename); } @* Gawk Begin, Body, End actions. @*2 Begin. @<|BEGIN|@>= BEGIN{ rec_cnt = 0; } @*2 Body. @<|Body|@>= { pass1_guidelines_verify($1); #pass2_correct($1,$2); } @*2 END. @<|END|@>= END{ #print "no records read: " NR; } @ Write out gawk program. @(ctan_chk.gawk@>= @; @<|is_file_a_directory|@>; @<|is_file_an_executable|@>; @<|chk_auxiliary_files|@>; @<|remove_file_s_extended_attributes|@>; @<|chk_file_permissions|@>; @<|chk_extended_file_attributes|@>; @<|chk_empty_files|@>; @<|chk_empty_directory|@>; @<|delete_file|@>; @<|chk_file_to_bypass_in_zip|@>; @; @; @<|BEGIN|@>; @<|Body|@>; @<|END|@>; @** Index.