git ssb

0+

cel / freecheck



Commit 7f59fc06d2300c374b6d0ee81788ce84dd588c69

commit from v0.21 tarball

Caleb Maclennan committed on 3/10/2014, 9:05:45 PM
Parent: 0e146f91b23a1bc9553cedbc2b2908c3912a95b9

Files changed

ChangeLogchanged
READMEchanged
TODOchanged
example_check.pschanged
freecheckchanged mode from 100644 to 100755
freecheck.cfgchanged
freecheck.cgichanged mode from 100644 to 100755
WARNINGadded
example_check.ps.newdeleted
ChangeLogView
@@ -2,8 +2,16 @@
22 - removed
33 * bug fix
44 % change
55
6 +Version 0.21, August 12, 2000
7 + % Changed the way the MICR line is generated & entered
8 + (See the freecheck.cfg file for details - it's changed)
9 + Previous algorithm was not flexible enough to generate
10 + many MICR lines out there. Should now handle all cases.
11 + + Added MICR line error checking - routing number checksum, etc.
12 + (Disabled with --test option)
13 +
614 Version 0.2, July 22, 2000
715 + Added error checking for nonexistant acct/style/blank
816 + Added options to show available accts/styles/blanks
917 + Added centimeter ("cm") def - dims can now be in cm
READMEView
@@ -1,9 +1,13 @@
1-FreeCheck v0.1 July 16, 2000
1 +FreeCheck v0.21 August 12, 2000
22 Eric Sandeen, <eric_sandeen@bigfoot.com>
33
4-WHY?
5----
4 +-----------------------------------------------
5 +| READ THE "WARNING" FILE BEFORE YOU PROCEED! |
6 +-----------------------------------------------
7 +
8 +WHY DID YOU WRITE THIS?
9 +-----------------------
610 MIPS/VersaCheck ticked me off with their (IMHO) shoddy check-printing
711 application, and their dismal customer service. So here you go.
812
913 REQUIREMENTS
@@ -16,8 +20,14 @@
1620
1721 You must also have either a PostScript printer, or a recent version
1822 of GhostScript. FreeCheck generates the check as a PostScript file.
1923
24 +Technically, you must also use MICR toner. At a minimum, use a real
25 +laster printer.
26 +
27 +Also, you should use security blank check stock, not just plain
28 +paper.
29 +
2030 CONFIGURATION
2131 -------------
2232 Edit the file freecheck.cfg to add your account information, and define
2333 any new check blanks or styles you want. Take a look at the [Global]
TODOView
@@ -2,9 +2,8 @@
22
33 * Implement some sort of bank logo inclusion (.eps file)
44 * Fix all the regexp problems that are surely in there
55 * Allow for a global config file, and a personal config file
6- * Write a CGI version, or include it in the same file
76 * Allow some defaults to be set in the config file to shorten command line
87 * Tweak PostScript to make sure nothing falls in the "forbidden" MICR area
98 * Print receipts or whatever on check blanks that allow space for that
109 * Command-line options for payee, date, memo, and amount
example_check.psView
@@ -1,182 +1,202 @@
1-%!
2-%---------------
3-%
4-% FreeCheck - a free check printing application released
5-% under the GNU General Public Licene.
6-%
7-% Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
8-%
9-% This program is free software; you can redistribute it and/or modify
10-% it under the terms of the GNU General Public License as published by
11-% the Free Software Foundation; either version 2 of the License, or
12-% (at your option) any later version.
13-%
14-% This program is distributed in the hope that it will be useful,
15-% but WITHOUT ANY WARRANTY; without even the implied warranty of
16-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17-% GNU General Public License for more details.
18-%
19-% You should have received a copy of the GNU General Public License
20-% along with this program; if not, write to the Free Software
21-% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22-%
23-%---------------
1 +%!
2 +%---------------
3 +%
4 +% FreeCheck - a free check printing application released
5 +% under the GNU General Public Licene.
6 +%
7 +% Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
8 +%
9 +% This program is free software; you can redistribute it and/or modify
10 +% it under the terms of the GNU General Public License as published by
11 +% the Free Software Foundation; either version 2 of the License, or
12 +% (at your option) any later version.
13 +%
14 +% This program is distributed in the hope that it will be useful,
15 +% but WITHOUT ANY WARRANTY; without even the implied warranty of
16 +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 +% GNU General Public License for more details.
18 +%
19 +% You should have received a copy of the GNU General Public License
20 +% along with this program; if not, write to the Free Software
21 +% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 +%
23 +%---------------
24 +
25 +% Let's get this out of the way first:
26 +/inch {72 mul} def
27 +
28 +%%%%%%%%%%%%%%%%%%%%%
29 +% Account info %
30 +% Text on the check %
31 +% (The Account File)%
32 +%%%%%%%%%%%%%%%%%%%%%
33 +
34 +
35 +% Things to define at each printing
36 +% ---------------------------------
37 +% ---------------------------------
38 +
39 +% Check number
40 +% ------------
41 +% Check number for first check on the page
42 +
43 +/CheckNumber 100 def
44 +
45 +% Parts to print
46 +% --------------
47 +% What exactly do we want to print? This is so that people can use
48 +% special MICR toner if they want, and print two-pass
49 +
50 +/PrintCheckBody true def
51 +/PrintMICRLine true def
52 +
53 +% Number of pages to print
54 +/NumPages 1 def
55 +
56 +% Prints a big VOID over the check
57 +/PrintVOID false def
58 +
59 +% Basic account information
60 +% -------------------------
61 +% -------------------------
62 +
63 +% Account Holder's Name, etc
64 +% --------------------------
65 +% If Name2 or Address2 are empty, they will not be printed
66 +
67 +/Name1 (JOHN SMITH) def
68 +/Name2 (MARY SMITH) def
69 +/Address1 (1234 Main Street) def
70 +/Address2 () def
71 +/CityStateZip (Anytown, USA 12345) def
72 +/PhoneNumber (512-555-1212) def
73 +
74 +% Bank information
75 +% ----------------
76 +% If BankAddr2 is empty, it will not be printed
77 +
78 +/BankName (GlobalMegaCorp, NA) def
79 +/BankAddr1 (123 Main Street) def
80 +/BankAddr2 (PO Box 45) def
81 +/BankCityStateZip (Anytown, USA 12345) def
82 +
83 +% MICR Line Information
84 +% ---------------------
2485
25-% Let's get this out of the way first:
26-/inch {72 mul} def
86 +% This is where you define your MICR line. Represent the On-Us symbol
87 +% with a "P", the dash symbol with a "-", and a space with a "S"
88 +% The routing symbol is represented with an "R"
2789
28-%%%%%%%%%%%%%%%%%%%%%
29-% Account info %
30-% Text on the check %
31-% (The Account File)%
32-%%%%%%%%%%%%%%%%%%%%%
90 +% Your check number will be filled in in either the Aux ON-US field, or
91 +% the On-Us field. Represent the check number spaces with "CCCC" (one
92 +% "C" for each check digit)
3393
94 +% Auxiliary On-Us field is everything to the left of the leftmost routing
95 +% symbol (|:) Include trailing spaces!
96 +/AuxOnUs () def % Include trailing spaces
3497
35-% Things to define at each printing
36-% ---------------------------------
37-% ---------------------------------
98 +% Routing / transit field is everything between, and including, the two
99 +% routing symbols (|:) Should be only 9 digits. Show routing symbols
100 +% with "R" on each end
101 +/Routing (R113000023R) def % Leftmost MICR numbers
38102
39-% Check number
40-% ------------
41-% Check number for first check on the page
103 +% On-Us field is everything to the RIGHT of the RIGHTMOST routing
104 +% symbol (|:). Include LEADING spaces!
105 +/OnUs (S005-775011251PSCCCC) def % Include leading spaces
42106
43-/CheckNumber 100 def
107 +% This is the fractional number at the top of the check
108 +/Fraction (12345/67890) def % Fraction at top of check
109 +
110 +% MICR Line placement "Tweaking"
111 +%-------------------------------
112 +% We add the MICR tweaking here (rather than in the check
113 +% blank definition) because it's likely the user will
114 +% need to change this. The blank definition may not be
115 +% writeable by the user
116 +
117 +/MICRVerTweak {0} def
118 +/MICRHorTweak {0} def
119 +
120 +%%%%%%%%%%%%%%%%%%%%%%%%%
121 +% Check Style %
122 +% Fonts and Layout Info %
123 +% (The Style File) %
124 +%%%%%%%%%%%%%%%%%%%%%%%%%
125 +
126 +% Font Names & Sizes
127 +% ------------------
128 +% The StandardFontSize is just the basic size for non-MICR
129 +% text. Things get scaled a bit from there (Names are larger than
130 +% addresses, etc)
131 +
132 +/StandardFontName /AvantGarde-Book def
133 +/StandardFontSize 9 def
134 +
135 +% This is NOT THE MICR FONT! It is the check number on top right
136 +/CheckNumFont /Helvetica-Bold def
137 +/CheckNumSize 14 def
138 +
139 +% Margins, etc, within the check itself
140 +% -------------------------------------
141 +
142 +/LeftMargin {0.2 inch} def
143 +/RightMargin {0.4 inch} def
144 +/TopMargin {0.2 inch} def
145 +
146 +% Check feature placement
147 +% -----------------------
148 +% (relative to bottom left corner of check)
149 +
150 +/MemoLineHeight {0.25} def
151 +/SignatureLineHeight {0.25} def
152 +/AmountLineHeight {0.50} def
153 +/PayeeLineHeight {0.60} def
154 +/BankInfoHeight {0.45} def
155 +/DateLineHeight {0.75} def
156 +
157 +%%%%%%%%%%%%%%%%%%%%%%%%%%
158 +% Check Blank Dimensions %
159 +% (The Check Blank File) %
160 +%%%%%%%%%%%%%%%%%%%%%%%%%%
161 +
162 +% Information about how the checks are laid out on the page
163 +% ---------------------------------------------------------
164 +
165 +/CheckHeight {2.85 inch} def
166 +/CheckWidth {5.96 inch} def
167 +/CheckHorOffset {2.54 inch} def % how far are checks from left edge of sheet
168 +/CheckVerOffset {2.48 inch} def % how far is bottom check from bottom of sheet
169 +/ChecksPerPage {3} def % How many checks are on the sheet? (vertical)
170 +
171 +%%%%%%%%%%%%%%%%%%%%%%%
172 +% Global Setup Values %
173 +%%%%%%%%%%%%%%%%%%%%%%%
174 +
175 +% MICR Font
176 +% ---------
177 +% For the MICR font, SIZE MATTERS! Make sure you have the right point
178 +% size for the particular MICR font you're using. Most (including
179 +% GnuMICR) are correct at 12 pts, but READ THE DOCS THAT CAME WITH
180 +% THE FONT! :)
181 +
182 +/MICRFontName /GnuMICR def
183 +/MICRFontSize 12 def
184 +
185 +% MICR Symbol Mapping
186 +% -------------------
187 +% Maps which characters show which MICR symbols in the font you're using
188 +% Approximate representations of these symbols, with names, below:
189 +% |: = TransitNumberSymbol
190 +% / = Amount
191 +% P = OnUs
192 +% - = Dash
193 +
194 +/TransitSymbol (A) def
195 +/OnUsSymbol (C) def
196 +/AmountSymbol (B) def
197 +/DashSymbol (D) def
44198
45-% Parts to print
46-% --------------
47-% What exactly do we want to print? This is so that people can use
48-% special MICR toner if they want, and print two-pass
49-
50-/PrintCheckBody true def
51-/PrintMICRLine true def
52-
53-% Number of pages to print
54-/NumPages 3 def
55-
56-% Prints a big VOID over the check
57-/PrintVOID true def
58-
59-% Basic account information
60-% -------------------------
61-% -------------------------
62-
63-% Account Holder's Name, etc
64-% --------------------------
65-% If Name2 or Address2 are empty, they will not be printed
66-
67-/Name1 (JOHN SMITH) def
68-/Name2 (MARY SMITH) def
69-/Address1 (1234 Main Street) def
70-/Address2 () def
71-/CityStateZip (Anytown, USA 12345) def
72-/PhoneNumber (512-555-1212) def
73-
74-% Bank information
75-% ----------------
76-% If BankAddr2 is empty, it will not be printed
77-
78-/BankName (GlobalMegaCorp, NA) def
79-/BankAddr1 (123 Main Street) def
80-/BankAddr2 (PO Box 45) def
81-/BankCityStateZip (Anytown, USA 12345) def
82-
83-% Account Information
84-% -------------------
85-
86-/RoutingNumber (012345678) def % Leftmost MICR numbers
87-/AccountNumber (1234567890) def % Middle MICR numbers
88-/Fraction (12345/67890) def % Fraction at top of check
89-
90-% MICR Line placement "Tweaking"
91-%-------------------------------
92-% We add the MICR tweaking here (rather than in the check
93-% blank definition) because it's likely the user will
94-% need to change this. The blank definition may not be
95-% writeable by the user
96-
97-/MICRVerTweak {0} def
98-/MICRHorTweak {0} def
99-
100-%%%%%%%%%%%%%%%%%%%%%%%%%
101-% Check Style %
102-% Fonts and Layout Info %
103-% (The Style File) %
104-%%%%%%%%%%%%%%%%%%%%%%%%%
105-
106-% Font Names & Sizes
107-% ------------------
108-% The StandardFontSize is just the basic size for non-MICR
109-% text. Things get scaled a bit from there (Names are larger than
110-% addresses, etc)
111-
112-/StandardFontName /AvantGarde-Book def
113-/StandardFontSize 9 def
114-
115-% This is NOT THE MICR FONT! It is the check number on top right
116-/CheckNumFont /Helvetica-Bold def
117-/CheckNumSize 14 def
118-
119-% Margins, etc, within the check itself
120-% -------------------------------------
121-
122-/LeftMargin {0.2 inch} def
123-/RightMargin {0.4 inch} def
124-/TopMargin {0.2 inch} def
125-
126-% Check feature placement
127-% -----------------------
128-% (relative to bottom left corner of check)
129-
130-/MemoLineHeight {0.25} def
131-/SignatureLineHeight {0.25} def
132-/AmountLineHeight {0.50} def
133-/PayeeLineHeight {0.60} def
134-/BankInfoHeight {0.45} def
135-/DateLineHeight {0.75} def
136-
137-%%%%%%%%%%%%%%%%%%%%%%%%%%
138-% Check Blank Dimensions %
139-% (The Check Blank File) %
140-%%%%%%%%%%%%%%%%%%%%%%%%%%
141-
142-% Information about how the checks are laid out on the page
143-% ---------------------------------------------------------
144-
145-/CheckHeight {2.85 inch} def
146-/CheckWidth {5.96 inch} def
147-/CheckHorOffset {2.52 inch} def % how far are checks from left edge of sheet
148-/CheckVerOffset {2.48 inch} def % how far is bottom check from bottom of sheet
149-/ChecksPerPage {3} def % How many checks are on the sheet? (vertical)
150-
151-%%%%%%%%%%%%%%%%%%%%%%%
152-% Global Setup Values %
153-%%%%%%%%%%%%%%%%%%%%%%%
154-
155-% MICR Font
156-% ---------
157-% For the MICR font, SIZE MATTERS! Make sure you have the right point
158-% size for the particular MICR font you're using. Most (including
159-% GnuMICR) are correct at 12 pts, but READ THE DOCS THAT CAME WITH
160-% THE FONT! :)
161-
162-/MICRFontName /GnuMICR def
163-/MICRFontSize 12 def
164-
165-% MICR Symbol Mapping
166-% -------------------
167-% Maps which characters show which MICR symbols in the font you're using
168-% Approximate representations of these symbols, with names, below:
169-% |: = TransitNumberSymbol
170-% / = Amount
171-% P = OnUs
172-% - = Dash
173-
174-/TransitSymbol (A) def
175-/OnUsSymbol (C) def
176-/AmountSymbol (B) def
177-/DashSymbol (D) def
178-
179199 % MICR Line placement
180200 % -------------------
181201 % This should be smack in the middle of the tolerance band...
182202 % Tweaks are accomplished by the user in the Global section
@@ -216,8 +236,129 @@
216236 neg 0 exch rmoveto % line down
217237 } if
218238 } def
219239
240 +% Fix up the MICR line components (replace placeholders with MICR
241 +% characters)
242 +% Argh... surely there's a better way - anyone? use "forall?"
243 +
244 +/FixMICR {
245 +
246 + /CheckNumStart -1 def
247 + /CheckNumEnd -1 def
248 + /CheckNumInOnUs false def
249 + /CheckNumInAuxOnUs false def
250 +
251 + % Get starting and ending positions for check number in
252 + % (Aux)OnUs field
253 + % (This will break if check number is entered in both fields)
254 +
255 + OnUs length 1 sub -1 0 {
256 + dup % dups the index
257 + OnUs exch get (C) 0 get eq {
258 + /CheckNumInOnUs true def
259 + % If end number not yet defined, define it
260 + CheckNumEnd 0 lt {
261 + /CheckNumEnd exch def
262 + } {
263 + /CheckNumStart exch def
264 + } ifelse
265 +
266 + } {
267 + pop
268 + } ifelse
269 + } for
270 +
271 + AuxOnUs length 1 sub -1 0 {
272 + dup % dups the index
273 + AuxOnUs exch get (C) 0 get eq {
274 + /CheckNumInAuxOnUs true def
275 + % If end number not yet defined, define it
276 + CheckNumEnd 0 lt {
277 + /CheckNumEnd exch def
278 + } {
279 + /CheckNumStart exch def
280 + } ifelse
281 +
282 + } {
283 + pop
284 + } ifelse
285 + } for
286 +
287 +
288 + % Replace "R" in routing number with actual transit number symbol
289 + % That's it - should be no spaces, dashes, or anything but digits
290 + Routing length 1 sub -1 0 {
291 + dup % dups the index
292 + Routing exch get (R) 0 get eq {
293 + Routing exch TransitSymbol 0 get put
294 + } {
295 + pop
296 + } ifelse
297 + } for
298 +
299 + % Replace "S" with space character in AuxOnUs
300 + AuxOnUs length 1 sub -1 0 {
301 + dup
302 + AuxOnUs exch get (S) 0 get eq {
303 + AuxOnUs exch ( ) 0 get put
304 + } {
305 + pop
306 + } ifelse
307 + } for
308 +
309 + % Replace "-" with dash character in AuxOnUs
310 + AuxOnUs length 1 sub -1 0 {
311 + dup
312 + AuxOnUs exch get (-) 0 get eq {
313 + AuxOnUs exch DashSymbol 0 get put
314 + } {
315 + pop
316 + } ifelse
317 + } for
318 +
319 + % Replace "P" with OnUs character in AuxOnUs
320 + AuxOnUs length 1 sub -1 0 {
321 + dup
322 + OnUs exch get (P) 0 get eq {
323 + OnUs exch OnUsSymbol 0 get put
324 + } {
325 + pop
326 + } ifelse
327 + } for
328 +
329 + % Replace "S" with space character in OnUs
330 + OnUs length 1 sub -1 0 {
331 + dup
332 + OnUs exch get (S) 0 get eq {
333 + OnUs exch ( ) 0 get put
334 + } {
335 + pop
336 + } ifelse
337 + } for
338 +
339 + % Replace "-" with dash character in OnUs
340 + OnUs length 1 sub -1 0 {
341 + dup
342 + OnUs exch get (-) 0 get eq {
343 + OnUs exch DashSymbol 0 get put
344 + } {
345 + pop
346 + } ifelse
347 + } for
348 +
349 + % Replace "P" with OnUs character in OnUs
350 + OnUs length 1 sub -1 0 {
351 + dup
352 + OnUs exch get (P) 0 get eq {
353 + OnUs exch OnUsSymbol 0 get put
354 + } {
355 + pop
356 + } ifelse
357 + } for
358 +
359 +} def
360 +
220361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221362 % Feature Printing Routines %
222363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223364
@@ -340,45 +481,50 @@
340481 % of the tolerance band
341482 CheckWidth 0.25 inch moveto
342483 -5.6875 inch 0 inch rmoveto
343484 MICRHorTweak MICRVerTweak rmoveto
485 + % Now we're at the nominal start of the routing number
344486
345- save
346- MICRFontName findfont
347- MICRFontSize scalefont
348- setfont
349- % If wide check, check number goes on the left
350- % with OnUS symbols around it
351- % so pad out the zeros, move back that far + space
352- CheckWidth 8.00 inch ge {
353- (0) stringwidth pop neg
354- CheckNumDigits mul
355- 3 add %2 OnUs symbols + space
356- 0 rmoveto
357- OnUsSymbol show
358- CheckNumDigits CheckNumberString length sub
359- { (0) show } repeat
360- CheckNumberString show
361- OnUsSymbol show
362- ( ) show
363- } if
364- TransitSymbol show
365- RoutingNumber show
366- TransitSymbol show
367- ( ) show
368- % Pad with spaces if acct number is short
369- 12 AccountNumber length sub {( ) show} repeat
370- AccountNumber show
371- OnUsSymbol show
372- ( ) show
373- % If we have a short check, check number goes here
374- CheckWidth 8.00 inch lt {
375- % Same deal, pad w/ 0s if short check number
376- CheckNumDigits CheckNumberString length sub
377- { (0) show } repeat
378- CheckNumberString show
379- } if
380- restore
487 + MICRFontName findfont
488 + MICRFontSize scalefont
489 + setfont
490 +
491 + % Number of digits in the CheckNumberString
492 + /CheckNumDigit CheckNumberString length 1 sub def
493 +
494 + CheckNumInAuxOnUs {
495 + CheckNumEnd -1 CheckNumStart {
496 + CheckNumDigit 0 ge {
497 + AuxOnUs exch CheckNumberString CheckNumDigit get put
498 + /CheckNumDigit CheckNumDigit 1 sub def
499 + } {
500 + AuxOnUs exch (0) 0 get put
501 + } ifelse
502 + } for
503 + } if
504 +
505 +
506 + AuxOnUs stringwidth pop neg 0 rmoveto
507 + AuxOnUs show
508 +
509 + Routing show
510 +
511 + CheckNumInOnUs {
512 + CheckNumEnd -1 CheckNumStart {
513 + CheckNumDigit 0 ge {
514 + OnUs exch CheckNumberString CheckNumDigit get put
515 + /CheckNumDigit CheckNumDigit 1 sub def
516 + } {
517 + OnUs exch (0) 0 get put
518 + } ifelse
519 + } for
520 + } if
521 +
522 + OnUs show
523 +
524 + StandardFontName findfont
525 + StandardFontSize scalefont
526 + setfont
381527 } def
382528
383529 /DrawCheckNumber {
384530 CheckWidth CheckHeight moveto
@@ -437,19 +583,20 @@
437583 50 scalefont
438584 setfont
439585 newpath
440586 CheckWidth 2 div 1 inch moveto
441-% 30 rotate
442-% (V O I D) stringwidth pop 0 moveto
443-% (V O I D) true charpath
587 + 30 rotate
588 + (V O I D) stringwidth pop 0 moveto
589 + (V O I D) true charpath
444590 stroke
445591 restore
446592 } def
447593
448594 /DrawCheck {
449595
450596 % Convert CheckNumber integer to a string
451597 CheckNumber CheckNumberString cvs
598 +
452599 PrintCheckBody {
453600 DrawBankInfo
454601 DrawAccountHolderInfo
455602 DrawMemoLine
@@ -471,8 +618,9 @@
471618 0 0 moveto
472619 CheckWidth 0 lineto
473620 CheckWidth CheckHeight lineto
474621 0 CheckHeight lineto
622 +
475623 0 0 lineto
476624
477625 DrawVOID
478626 } if
@@ -481,8 +629,12 @@
481629
482630
483631 /CurrentPage 1 def
484632
633 +% Replace symbol placeholders with actual glyphs
634 +% Also get starting and ending position for check number
635 +FixMICR
636 +
485637 NumPages -1 1 {
486638 /CheckNumber CheckNumber ChecksPerPage add def
487639 CheckHorOffset CheckVerOffset translate
488640
@@ -506,5 +658,4 @@
506658 /CheckNumber CheckNumber ChecksPerPage add def
507659 /CurrentPage CurrentPage 1 add def
508660
509661 } for
510-
freecheckView
@@ -62,10 +62,11 @@
6262 BankName (value)
6363 BankAddr1 (value)
6464 BankAddr2 (value)
6565 BankCityStateZip (value)
66- RoutingNumber (value)
67- AccountNumber (value)
66 + AuxOnUs (value)
67 + Routing (value)
68 + OnUs (value)
6869 Fraction (value)
6970 PrintVOID {value}
7071 # Styles
7172 StandardFontName /value
@@ -207,11 +208,100 @@
207208 while ( $opt_cgi =~ /(^\w+)\s+?(.*$)/mcg ) {
208209 $Definitions{$1} = $2;
209210 }
210211
211-# If there's a dash in the account string, replace it with the dash symbol
212-$Definitions{"AccountNumber"} =~ s/\-/$Definitions{"DashSymbol"}/g;
212 +##################
213 +# Error Checking #
214 +##################
213215
216 +$error = "";
217 +
218 +# Make sure that MICR line is only numbers and symbols
219 +
220 +if ( $Definitions{"Routing"} !~ /^R[0-9]+R$/ ) {
221 + $error = $error . "Error - Routing number must be numeric, with an \"R\" on each end\n";
222 +}
223 +
224 +if ( $Definitions{"AuxOnUs"} !~ /^[0-9\-CPS]*$/ ) {
225 + $error = $error . "Error - Auxiliary On-Us field may only be numeric, with \"-\", and MICR symbols (C,P,S)\n";
226 +}
227 +
228 +if ( $Definitions{"OnUs"} !~ /^[0-9\-CPS]+$/ ) {
229 + $error = $error . "Error - On-Us field may only be numeric, with \"-\", and MICR symbols (C,P,S)\n";
230 +}
231 +
232 +if ( $Definitions{"CheckNumber"} !~ /^[0-9]+$/ ) {
233 + $error = $error . "Error - Check number must be numeric \n";
234 +}
235 +
236 +if ( $Definitions{"NumPages"} !~ /^[0-9]+$/ ) {
237 + $error = $error . "Error - Number of pages must be numeric\n";
238 +}
239 +
240 +if ( $Definitions{"Fraction"} !~ /^[0-9]{2}\s*\-\s*[0-9]{1,4}\s*\/\s*[0-9]{3,4}$/ ) {
241 + $error = $error . "Error - Routing fraction must be numeric, with a \"-\" in the numerator\n";
242 +}
243 +
244 +# Get routing symbol and institution number from routing number
245 +$RoutingSymbol = substr($Definitions{"Routing"},1,4);
246 +$Institution = substr($Definitions{"Routing"},5,4);
247 +
248 +# Strip any leading zeros...
249 +# Only should be one on routing...
250 +$RoutingSymbol =~ s/^0//;
251 +# One or more on institution
252 +$Institution =~ s/^0+//;
253 +
254 +# Fraction format:
255 +#
256 +# 2 digits, a "-", institution number (no leading zeros)
257 +# ------------------------------------------------------
258 +# routing number (no leading zeros)
259 +
260 +
261 +if ( $Definitions{"Fraction"} !~ /^[0-9]{2}\-${Institution}\/${RoutingSymbol}$/ ) {
262 + $error = $error . "Error - Routing fraction does not match routing number\n";
263 +}
264 +
265 +
266 +# Test the MICR line for correctness
267 +if ( length ($Definitions{"Routing"}) != 11 ) {
268 + $error = $error . "Error - Routing number must be exactly 9 digits long, with
269 + an \"R\" on each end\n";
270 +}
271 +
272 +# Test the MICR checksum
273 +# Don't forget the real routing number is sandwiched between "Rs"
274 +
275 +unless ( ( $Definitions{"Routing"} !~ /^R[0-9]+R$/) || ( length ($Definitions{"Routing"}) != 11 ) ){
276 +
277 + $CheckSum = 0;
278 +
279 + @CheckSumMults = (3, 7, 1, 3, 7, 1, 3, 7);
280 + for ($Digit = 1; $Digit < 9; $Digit++) {
281 + $CheckSum = $CheckSum +
282 + $CheckSumMults[$Digit-1] * substr($Definitions{"Routing"}, $Digit, 1);
283 + }
284 +
285 + $CheckSum = 10 - ($CheckSum % 10);
286 +
287 + # Kludge alert...
288 + if ($CheckSum == 10) {
289 + $CheckSum = 0;
290 + }
291 +
292 + if ( $CheckSum ne substr($Definitions{"Routing"}, 9, 1) ) {
293 + $error = $error . "Error - Routing Number Checksum Incorrect\n";
294 + }
295 +}
296 +
297 +
298 +# die() if we got errors
299 +if ( $error && !$opt_test ) {
300 + print $error;
301 + die("Errors Encountered\n");
302 +}
303 +
214304 # Print PostScript
215305
216306 # Initial stuff:
217307
@@ -224,9 +314,9 @@
224314 # Then print the main body
225315 Print_Body();
226316
227317 # Update the config file with the new check number, if it's not just a test
228-if (!$opt_test) {
318 +if (!$opt_test && !$opt_cgi) {
229319 $next_check_number = $Definitions{"CheckNumber"}
230320 + ($Definitions{"NumPages"} * $Definitions{"ChecksPerPage"});
231321
232322 $config_file = Replace_Val($config_file, "Account", $opt_account,
@@ -339,9 +429,9 @@
339429 $section = $+;
340430 if ( $section =~/CheckBlank\s+(.+)/i ) {
341431 $checkblanks = "$+ $checkblanks";
342432 } elsif ( $section =~/Style\s+(.+)/i ) {
343- $checkstyles = "$+ $styles";
433 + $checkstyles = "$+ $checkstyles";
344434 } elsif ( $section =~/Account\s+(.+)/i ) {
345435 $accounts = "$+ $accounts";
346436 } elsif ( $section =~/Global/i ) {
347437 $global_found = "true";
@@ -390,17 +480,19 @@
390480 # This is the main body of the postscript file, that acts on all of the
391481 # definitions we got from the config file.
392482
393483 print <<END_OF_POSTSCRIPT
484 +
394485 % Other Constants:
395486
396487 % Size of the rectangular box for the amount (digits)
397488 /AmountBoxWidth {1 inch} def
398489 /AmountBoxHeight {0.25 inch} def
399490
400491 /LineWidth {0.3} def
401492
402-% Convert CheckNumber integer to a string of appropriate length
493 +% Max number of digits in check number, and allocate string
494 +/CheckNumDigits 4 def
403495 /CheckNumberString CheckNumber log floor 1 add cvi string def
404496
405497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406498 % Helpful Printing Routines %
@@ -419,8 +511,129 @@
419511 neg 0 exch rmoveto % line down
420512 } if
421513 } def
422514
515 +% Fix up the MICR line components (replace placeholders with MICR
516 +% characters)
517 +% Argh... surely there's a better way - anyone? use "forall?"
518 +
519 +/FixMICR {
520 +
521 + /CheckNumStart -1 def
522 + /CheckNumEnd -1 def
523 + /CheckNumInOnUs false def
524 + /CheckNumInAuxOnUs false def
525 +
526 + % Get starting and ending positions for check number in
527 + % (Aux)OnUs field
528 + % (This will break if check number is entered in both fields)
529 +
530 + OnUs length 1 sub -1 0 {
531 + dup % dups the index
532 + OnUs exch get (C) 0 get eq {
533 + /CheckNumInOnUs true def
534 + % If end number not yet defined, define it
535 + CheckNumEnd 0 lt {
536 + /CheckNumEnd exch def
537 + } {
538 + /CheckNumStart exch def
539 + } ifelse
540 +
541 + } {
542 + pop
543 + } ifelse
544 + } for
545 +
546 + AuxOnUs length 1 sub -1 0 {
547 + dup % dups the index
548 + AuxOnUs exch get (C) 0 get eq {
549 + /CheckNumInAuxOnUs true def
550 + % If end number not yet defined, define it
551 + CheckNumEnd 0 lt {
552 + /CheckNumEnd exch def
553 + } {
554 + /CheckNumStart exch def
555 + } ifelse
556 +
557 + } {
558 + pop
559 + } ifelse
560 + } for
561 +
562 +
563 + % Replace "R" in routing number with actual transit number symbol
564 + % That's it - should be no spaces, dashes, or anything but digits
565 + Routing length 1 sub -1 0 {
566 + dup % dups the index
567 + Routing exch get (R) 0 get eq {
568 + Routing exch TransitSymbol 0 get put
569 + } {
570 + pop
571 + } ifelse
572 + } for
573 +
574 + % Replace "S" with space character in AuxOnUs
575 + AuxOnUs length 1 sub -1 0 {
576 + dup
577 + AuxOnUs exch get (S) 0 get eq {
578 + AuxOnUs exch ( ) 0 get put
579 + } {
580 + pop
581 + } ifelse
582 + } for
583 +
584 + % Replace "-" with dash character in AuxOnUs
585 + AuxOnUs length 1 sub -1 0 {
586 + dup
587 + AuxOnUs exch get (-) 0 get eq {
588 + AuxOnUs exch DashSymbol 0 get put
589 + } {
590 + pop
591 + } ifelse
592 + } for
593 +
594 + % Replace "P" with OnUs character in AuxOnUs
595 + AuxOnUs length 1 sub -1 0 {
596 + dup
597 + OnUs exch get (P) 0 get eq {
598 + OnUs exch OnUsSymbol 0 get put
599 + } {
600 + pop
601 + } ifelse
602 + } for
603 +
604 + % Replace "S" with space character in OnUs
605 + OnUs length 1 sub -1 0 {
606 + dup
607 + OnUs exch get (S) 0 get eq {
608 + OnUs exch ( ) 0 get put
609 + } {
610 + pop
611 + } ifelse
612 + } for
613 +
614 + % Replace "-" with dash character in OnUs
615 + OnUs length 1 sub -1 0 {
616 + dup
617 + OnUs exch get (-) 0 get eq {
618 + OnUs exch DashSymbol 0 get put
619 + } {
620 + pop
621 + } ifelse
622 + } for
623 +
624 + % Replace "P" with OnUs character in OnUs
625 + OnUs length 1 sub -1 0 {
626 + dup
627 + OnUs exch get (P) 0 get eq {
628 + OnUs exch OnUsSymbol 0 get put
629 + } {
630 + pop
631 + } ifelse
632 + } for
633 +
634 +} def
635 +
423636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424637 % Feature Printing Routines %
425638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426639
@@ -543,45 +756,50 @@
543756 % of the tolerance band
544757 CheckWidth 0.25 inch moveto
545758 -5.6875 inch 0 inch rmoveto
546759 MICRHorTweak MICRVerTweak rmoveto
760 + % Now we're at the nominal start of the routing number
547761
548- save
549- MICRFontName findfont
550- MICRFontSize scalefont
551- setfont
552- % If wide check, check number goes on the left
553- % with OnUS symbols around it
554- % so pad out the zeros, move back that far + space
555- CheckWidth 8.00 inch ge {
556- (0) stringwidth pop neg
557- CheckNumDigits mul
558- 3 add %2 OnUs symbols + space
559- 0 rmoveto
560- OnUsSymbol show
561- CheckNumDigits CheckNumberString length sub
562- { (0) show } repeat
563- CheckNumberString show
564- OnUsSymbol show
565- ( ) show
566- } if
567- TransitSymbol show
568- RoutingNumber show
569- TransitSymbol show
570- ( ) show
571- % Pad with spaces if acct number is short
572- 12 AccountNumber length sub {( ) show} repeat
573- AccountNumber show
574- OnUsSymbol show
575- ( ) show
576- % If we have a short check, check number goes here
577- CheckWidth 8.00 inch lt {
578- % Same deal, pad w/ 0s if short check number
579- CheckNumDigits CheckNumberString length sub
580- { (0) show } repeat
581- CheckNumberString show
582- } if
583- restore
762 + MICRFontName findfont
763 + MICRFontSize scalefont
764 + setfont
765 +
766 + % Number of digits in the CheckNumberString
767 + /CheckNumDigit CheckNumberString length 1 sub def
768 +
769 + CheckNumInAuxOnUs {
770 + CheckNumEnd -1 CheckNumStart {
771 + CheckNumDigit 0 ge {
772 + AuxOnUs exch CheckNumberString CheckNumDigit get put
773 + /CheckNumDigit CheckNumDigit 1 sub def
774 + } {
775 + AuxOnUs exch (0) 0 get put
776 + } ifelse
777 + } for
778 + } if
779 +
780 +
781 + AuxOnUs stringwidth pop neg 0 rmoveto
782 + AuxOnUs show
783 +
784 + Routing show
785 +
786 + CheckNumInOnUs {
787 + CheckNumEnd -1 CheckNumStart {
788 + CheckNumDigit 0 ge {
789 + OnUs exch CheckNumberString CheckNumDigit get put
790 + /CheckNumDigit CheckNumDigit 1 sub def
791 + } {
792 + OnUs exch (0) 0 get put
793 + } ifelse
794 + } for
795 + } if
796 +
797 + OnUs show
798 +
799 + StandardFontName findfont
800 + StandardFontSize scalefont
801 + setfont
584802 } def
585803
586804 /DrawCheckNumber {
587805 CheckWidth CheckHeight moveto
@@ -651,8 +869,9 @@
651869 /DrawCheck {
652870
653871 % Convert CheckNumber integer to a string
654872 CheckNumber CheckNumberString cvs
873 +
655874 PrintCheckBody {
656875 DrawBankInfo
657876 DrawAccountHolderInfo
658877 DrawMemoLine
@@ -674,8 +893,9 @@
674893 0 0 moveto
675894 CheckWidth 0 lineto
676895 CheckWidth CheckHeight lineto
677896 0 CheckHeight lineto
897 +
678898 0 0 lineto
679899
680900 DrawVOID
681901 } if
@@ -684,8 +904,12 @@
684904
685905
686906 /CurrentPage 1 def
687907
908 +% Replace symbol placeholders with actual glyphs
909 +% Also get starting and ending position for check number
910 +FixMICR
911 +
688912 NumPages -1 1 {
689913 /CheckNumber CheckNumber ChecksPerPage add def
690914 CheckHorOffset CheckVerOffset translate
691915
@@ -710,8 +934,9 @@
710934 /CurrentPage CurrentPage 1 add def
711935
712936 } for
713937
938 +
714939 END_OF_POSTSCRIPT
715940 ;
716941
717942 }
freecheck.cfgView
@@ -114,13 +114,36 @@
114114 # BankAddr1 = 6780 Main Street
115115 # BankAddr2 = Suite 45
116116 # BankCityStateZip = Anytown, USA 12345
117117
118-# Account Information
119-# -------------------
118 +# MICR Information
119 +# ----------------
120120
121-# RoutingNumber = 012345678 # Leftmost MICR numbers
122-# AccountNumber = 1234567890 # Middle MICR numbers
121 +# This is where you define your MICR line. Represent the On-Us symbol
122 +# with a "P", the dash symbol with a "-", and a space with a "S"
123 +# The routing symbol is represented with an "R"
124 +
125 +# Your check number will be filled in in either the Aux On-Us field, or in
126 +# the On-Us field. Represent the check number spaces with "CCCC" (one
127 +# "C" for each check digit)
128 +
129 +# Auxiliary On-Us field is everything to the left of the leftmost routing
130 +# symbol (|:) Include trailing spaces! (Aux On-Us may be blank for
131 +# personal checks)
132 +
133 +# Routing field is everything between the two
134 +# routing symbols (|:) Should be only 9 digits.
135 +
136 +# On-Us field is everything to the RIGHT of the RIGHTMOST routing
137 +# symbol (|:). Include LEADING spaces!
138 +
139 +# AuxOnUs = # Everything to left of first |:
140 +# Routing = R012345678R # Everything between |: |:, 9 digits
141 +# OnUs = S1392812PSCCCC # Everything to right of last |:
142 +
143 +# Routing Fraction
144 +# ----------------
145 +
123146 # Fraction = 12345/67890 # Fraction at top of check
124147
125148 [Account Sample]
126149 CheckNumber = 100
@@ -135,12 +158,13 @@
135158 PhoneNumber = 512-555-1212
136159 BankName = MegaCorp Bank, NA
137160 BankAddr1 = 6780 Main Street
138161 BankAddr2 = Suite 45
139-BankCityStateZip = Anytown, USA 12345
140-RoutingNumber = 012345678
141-AccountNumber = 1234567890
142-Fraction = 12345/67890
162 +BankCityStateZip = Anytown, USA 12345
163 +AuxOnUs =
164 +Routing = R123456780R
165 +OnUs = S4232268154PSCCCC
166 +Fraction = 37-5678/1234
143167
144168 ################
145169 # Check Styles #
146170 ################
freecheck.cgiView
@@ -46,8 +46,12 @@
4646
4747 # The path to the GhostScript executable, with escaped "/"s
4848 $GS = "\/usr\/bin\/gs";
4949
50 +# Parameters to GhostScript to generate PDFs (trailing "-" means STDIN
51 +$PDFOptions = "-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- -";
52 +
53 +
5054 # Get the cookie to set the defaults, if it's there...
5155 %pairs_hash = cookie('FreeCheck');
5256
5357 # If it's not there, set minimum defaults so the main script won't bonk
@@ -58,91 +62,144 @@
5862 "CheckNumber", "100");
5963 }
6064
6165 # If we have no parameters passed, generate the initial page with default vals
66 +# Those defaults might be from a cookie (above) if one has been set.
6267 if (!param()) {
6368 print header;
6469 print start_html('FreeCheck Online'),
6570 #"Cookie:",br,
6671 #%pairs_hash,
6772 h1('FreeCheck'),
6873 "A free check printing utility",
6974 br,
75 + "Version 0.21",
76 + br,
7077 "Copyright (C) 2000 Eric Sandeen (eric_sandeen @ bigfoot.com)",
7178 hr,
72-
79 + "WARNING - unless you're brave, treat this application as a
80 + proof-of-concept, rather than a useful utility. I have not
81 + had a chance to test this stuff with a bank yet, and I'm also
82 + a bit concerned about the accuracy during conversion to
83 + PDF. Just don't go paying your rent with this yet, ok? :)",
84 + hr,
7385 start_form,
7486 submit( -name=>"Submit",
7587 -label=>" Get my checks! "),
7688 h2('Check Information'),
7789 h3('Account Holder Information'),
7890
7991 textfield( -name=>'Name1',
80- -default=>$pairs_hash{"Name1"}),
92 + -default=>$pairs_hash{"Name1"},
93 + -maxlength=>50),
8194 " Name 1", br,
8295
8396 textfield( -name=>'Name2',
84- -default=>$pairs_hash{"Name2"}),
97 + -default=>$pairs_hash{"Name2"},
98 + -maxlength=>50),
8599 " Name 2", br,
86100
87101 textfield( -name=>'Address1',
88- -default=>$pairs_hash{"Address1"}),
102 + -default=>$pairs_hash{"Address1"},
103 + -maxlength=>50),
89104 " Address Line 1", br,
90105
91106 textfield( -name=>'Address2',
92- -default=>$pairs_hash{"Address2"}),
107 + -default=>$pairs_hash{"Address2"},
108 + -maxlength=>50),
93109 " Address Line 2", br,
94110
95111 textfield( -name=>'CityStateZip',
96- -default=>$pairs_hash{"CityStateZip"}),
112 + -default=>$pairs_hash{"CityStateZip"},
113 + -maxlength=>50),
97114 " City, State, Zip", br,
98115
99116 textfield( -name=>'PhoneNumber',
100- -default=>$pairs_hash{"PhoneNumber"}),
117 + -default=>$pairs_hash{"PhoneNumber"},
118 + -maxlength=>50),
101119 " Phone Number", br,
102120
103- h3('Account Information'),
104- textfield( -name=>'RoutingNumber',
105- -default=>$pairs_hash{"RoutingNumber"},
106- -size=>9, -maxlength=>9),
107- " Routing Number", br,
121 + h3('MICR Line Information'),
122 + "Pay close attention here - this is where you enter the MICR
123 + line at the bottom of your check. For the following symbols,
124 + use these characters:", p,
108125
109- textfield( -name=>'AccountNumber',
110- -default=>$pairs_hash{"AccountNumber"}),
111- " Account Number", br,
126 + hr,
127 + img {-src=>'/images/transit.gif'}, " = \"R\"", br,
128 + img {-src=>'/images/onus.gif'}, " = \"P\"", br,
129 + img {-src=>'/images/dash.gif'}, " = \"-\" (dash, or minus)", p,
130 + "For spaces, enter \"S\"", p,
131 + "For check numbers, enter a \"C\" for each check digit", p,
132 + hr,
112133
134 + "Auxiliary On-Us field - Everything to the left of the leftmost ",
135 + img {-src=>'/images/transit.gif'}, " symbol", br,
136 + em("Don't forget to include trailing spaces (\"S\")!"), br,
137 + "This field may not be present on personal checks", br,
138 +
139 + textfield( -name=>'AuxOnUs',
140 + -default=>$pairs_hash{"AuxOnUs"},
141 + -maxlength=>50),
142 +
143 + " Auxiliary On-Us field", p,
144 +
145 + "Transit / Routing Field - 9 numbers between, and including, the ",
146 + img {-src=>'/images/transit.gif'}, " symbols", br,
147 +
148 + textfield( -name=>'Routing',
149 + -default=>$pairs_hash{"Routing"},
150 + -size=>11, -maxlength=>11),
151 +
152 + " Routing Field", p,
153 +
154 + "On-Us field - everything to the right of the rightmost ",
155 + img {-src=>'/images/transit.gif'}, " symbol", br,
156 + em("Don't forget to include leading spaces (\"S\")!"), br,
157 +
158 + textfield( -name=>'OnUs',
159 + -default=>$pairs_hash{"OnUs"},
160 + -maxlength=>50),
161 +
162 + " On-Us field", p,
163 +
113164 textfield( -name=>'Fraction',
114- -default=>$pairs_hash{"Fraction"}),
115- " Fraction (top of check)", br,
165 + -default=>$pairs_hash{"Fraction"},
166 + -maxlength=>50),
116167
168 + " Fraction (printed at top right of check)", br,
169 +
117170 h3('Bank Information'),
118171 textfield( -name=>'BankName',
119- -default=>$pairs_hash{"BankName"}),
172 + -default=>$pairs_hash{"BankName"},
173 + -maxlength=>50),
120174 " Bank Name", br,
121175
122176 textfield( -name=>'BankAddr1',
123- -default=>$pairs_hash{"BankAddr1"}),
177 + -default=>$pairs_hash{"BankAddr1"},
178 + -maxlength=>50),
124179 " Bank Address1", br,
125180
126181 textfield( -name=>'BankAddr2',
127- -default=>$pairs_hash{"BankAddr2"}),
182 + -default=>$pairs_hash{"BankAddr2"},
183 + -maxlength=>50),
128184 " Bank Address 2", br,
129185
130186 textfield( -name=>'BankCityStateZip',
131- -default=>$pairs_hash{"BankCityStateZip"}),
187 + -default=>$pairs_hash{"BankCityStateZip"},
188 + -maxlength=>50),
132189 " Bank City, State, Zip", br,
133190
134191 h2('Printing Options'),
135192 textfield( -name=>'CheckNumber',
136193 -default=>$pairs_hash{"CheckNumber"},
137- -size=>7,
138- -maxlength=>7),
194 + -size=>10,
195 + -maxlength=>10),
139196 " Starting Check Number",
140197 br,
141198
142199 "Select check style: ",
143200 popup_menu( -name=>'CheckStyle',
144- -values=>['Normal'],
201 + -values=>['Normal','Quicken_Personal'],
145202 -default=>$pairs_hash{"CheckStyle"}),
146203 br,
147204
148205 "Select check blank: ",
@@ -176,8 +233,11 @@
176233 "Select Output Format:",
177234 br,
178235 em("Be sure to de-select \"Fit to Page\" when printing PDFs"),
179236 br,
237 + em("To view PostScript correctly, you must have the
238 + GnuMICR font installed locally"),
239 + br,
180240 radio_group( -name=>'OutputType',
181241 -values=>['PDF', 'PostScript'],
182242 -labels=>{'PDF'=>' PDF',
183243 'PostScript'=>' PostScript'},
@@ -188,9 +248,9 @@
188248 "Number of Pages to Print: ",
189249 textfield( -name=>'NumPages',
190250 -default=>$pairs_hash{"NumPages"},
191251 -size=>2,
192- -maxlength=>80),
252 + -maxlength=>1),
193253 p,
194254
195255 "Save information in a cookie?",
196256 br,
@@ -281,17 +341,19 @@
281341 # Sanitize $pairs_string and $arguments
282342 # Let's not go spawning any new shells (this is minimal security...)
283343 # Also checks for SSI strings
284344
345 + # Look for SSI
285346 if ($pairs_string =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
286347 kill_input();
287348 }
288349
289- if ($pairs_string =~ /[;><\*`\|]/s) {
350 + if ($arguments =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
290351 kill_input();
291352 }
292353
293- if ($arguments =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
354 + # Look for shell metachars
355 + if ($pairs_string =~ /[;><\*`\|]/s) {
294356 kill_input();
295357 }
296358
297359 if ($arguments =~ /[;><\*`\|]/s) {
@@ -311,20 +373,8 @@
311373 -path=>script_name(),
312374 -domain=>server_name());
313375 }
314376
315- # Generate the apropriate header.
316- if (param("OutputType") eq "PDF") {
317- $PDFConvert = "\| $GS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- -";
318- print header( -type=>'application/pdf',
319- -attachment=>'mychecks.pdf',
320- -cookie=>$cookie);
321- } else {
322- print header( -type=>'application/postscript',
323- -attachment=>'mychecks.ps',
324- -cookie=>$cookie);
325- }
326-
327377 # Generate the actual output.
328378 # The PDF thing might become an option in the main script
329379 # soon...
330380 ###########################################
@@ -334,10 +384,55 @@
334384 # STRINGS PASSED IN FROM THE FORM. A FEEBLE EFFORT HAS BEEN
335385 # MADE TO SANITIZE THOSE STRINGS, BUT THERE COULD STILL BE
336386 # A SECURITY RISK HERE. YOU HAVE BEEN WARNED
337387
338- print (`.\/freecheck --cgi \"$pairs_string\" $arguments $PDFConvert`);
388 + if (param("OutputType") eq "PDF") {
389 + $PDFConvert = "\| $GS $PDFOptions";
390 + }
339391
392 + #print (`.\/freecheck --cgi \"$pairs_string\" $arguments \| $GS $PDFConvert`);
393 + # This is just the postscript result, or the error:
394 + $Result = `.\/freecheck --cgi \"$pairs_string\" $arguments`;
395 +
396 + if (length($Result) < 500 ) { # Anything this short is an error...
397 + print header;
398 + print start_html("We encountered an error...");
399 + print h1("There are some errors on your form:");
400 + # HTML-ify the result ( \n to <br> )
401 + $Result =~ s/\n/<br>/gsm;
402 + print $Result;
403 + print br;
404 + print "Press the Back button on your browser to fix them...";
405 + print p;
406 + print em("If you select \"Print voided test checks\" then
407 + MICR consistency checking will not be performed");
408 + print end_html;
409 + exit;
410 + }
411 +
412 + # Otherwise, generate the apropriate header...
413 + # And send the data
414 + if (param("OutputType") eq "PDF") {
415 + print header( -type=>'application/pdf',
416 + -attachment=>'mychecks.pdf',
417 + -cookie=>$cookie);
418 +
419 + # This is bad... running the script a 2nd time... must be a better
420 + # way. Like open(PDF, "|$GS $PDFConvert
421 + #open (PDF, "| $PDFConvert");
422 + #print PDF $Result;
423 + #close(PDF);
424 +
425 + print (`.\/freecheck --cgi \"$pairs_string\" $arguments \| $GS $PDFOptions`);
426 + } else {
427 + print header( -type=>'application/postscript',
428 + -attachment=>'mychecks.ps',
429 + -cookie=>$cookie);
430 +
431 + print $Result;
432 + }
433 +
434 + exit;
340435 }
341436
342437 sub kill_input {
343438 print header;
@@ -345,7 +440,9 @@
345440 print "You seem to have some shell metacharacters in your ";
346441 print "entered strings. Sorry, you can't do that...";
347442 print p;
348443 print "Please get those funky things out of your form, and try again";
444 + print p;
445 + print "You can hit the back button to go back to your form.";
349446 print end_html;
350447 exit;
351448 }
WARNINGView
@@ -1,0 +1,23 @@
1 +WARNING - WARNING - WARNING - WARNING
2 +
3 +This app is in development. It may work great for you, and it may not...
4 +MICR printing is a fairly tricky business, at least if you listen to the
5 +people in the industry. Some tips to make sure this goes well for you:
6 +
7 +1) Use magnetic (MICR) toner for the MICR line (NOT for the rest of the check -
8 + see the --nomicr and --nobody options). This is the "official" way
9 + to do it. At a minimum, use a laser printer. Bubble jets, ink jets,
10 + and (need I say it?) dot-matrix printers will not give useable results.
11 +
12 +2) Use security check blanks / stock. This is available various places
13 + around the web, and it's not terribly expensive. Do NOT just print
14 + on plain paper!
15 +
16 +3) Make sure your printed MICR line is _exactly_ as shown on your bank-printed
17 + checks. If you can't make it the same, let me know what the problem is,
18 + and I'll see if it's a bug.
19 +
20 +And, as mentioned various other places, if your bank charges you a fee
21 +for malformed checks.... you have been warned. :)
22 +
23 +WARNING - WARNING - WARNING - WARNING
example_check.ps.newView
@@ -1,510 +1,0 @@
1-%!
2-%---------------
3-%
4-% FreeCheck - a free check printing application released
5-% under the GNU General Public Licene.
6-%
7-% Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
8-%
9-% This program is free software; you can redistribute it and/or modify
10-% it under the terms of the GNU General Public License as published by
11-% the Free Software Foundation; either version 2 of the License, or
12-% (at your option) any later version.
13-%
14-% This program is distributed in the hope that it will be useful,
15-% but WITHOUT ANY WARRANTY; without even the implied warranty of
16-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17-% GNU General Public License for more details.
18-%
19-% You should have received a copy of the GNU General Public License
20-% along with this program; if not, write to the Free Software
21-% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22-%
23-%---------------
24-
25-% Let's get this out of the way first:
26-/inch {72 mul} def
27-
28-%%%%%%%%%%%%%%%%%%%%%
29-% Account info %
30-% Text on the check %
31-% (The Account File)%
32-%%%%%%%%%%%%%%%%%%%%%
33-
34-
35-% Things to define at each printing
36-% ---------------------------------
37-% ---------------------------------
38-
39-% Check number
40-% ------------
41-% Check number for first check on the page
42-
43-/CheckNumber 100 def
44-
45-% Parts to print
46-% --------------
47-% What exactly do we want to print? This is so that people can use
48-% special MICR toner if they want, and print two-pass
49-
50-/PrintCheckBody true def
51-/PrintMICRLine true def
52-
53-% Number of pages to print
54-/NumPages 3 def
55-
56-% Prints a big VOID over the check
57-/PrintVOID false def
58-
59-% Basic account information
60-% -------------------------
61-% -------------------------
62-
63-% Account Holder's Name, etc
64-% --------------------------
65-% If Name2 or Address2 are empty, they will not be printed
66-
67-/Name1 (JOHN SMITH) def
68-/Name2 (MARY SMITH) def
69-/Address1 (1234 Main Street) def
70-/Address2 () def
71-/CityStateZip (Anytown, USA 12345) def
72-/PhoneNumber (512-555-1212) def
73-
74-% Bank information
75-% ----------------
76-% If BankAddr2 is empty, it will not be printed
77-
78-/BankName (GlobalMegaCorp, NA) def
79-/BankAddr1 (123 Main Street) def
80-/BankAddr2 (PO Box 45) def
81-/BankCityStateZip (Anytown, USA 12345) def
82-
83-% Account Information
84-% -------------------
85-
86-/RoutingNumber (012345678) def % Leftmost MICR numbers
87-/AccountNumber (1234567890) def % Middle MICR numbers
88-/Fraction (12345/67890) def % Fraction at top of check
89-
90-% MICR Line placement "Tweaking"
91-%-------------------------------
92-% We add the MICR tweaking here (rather than in the check
93-% blank definition) because it's likely the user will
94-% need to change this. The blank definition may not be
95-% writeable by the user
96-
97-/MICRVerTweak {0} def
98-/MICRHorTweak {0} def
99-
100-%%%%%%%%%%%%%%%%%%%%%%%%%
101-% Check Style %
102-% Fonts and Layout Info %
103-% (The Style File) %
104-%%%%%%%%%%%%%%%%%%%%%%%%%
105-
106-% Font Names & Sizes
107-% ------------------
108-% The StandardFontSize is just the basic size for non-MICR
109-% text. Things get scaled a bit from there (Names are larger than
110-% addresses, etc)
111-
112-/StandardFontName /AvantGarde-Book def
113-/StandardFontSize 9 def
114-
115-% This is NOT THE MICR FONT! It is the check number on top right
116-/CheckNumFont /Helvetica-Bold def
117-/CheckNumSize 14 def
118-
119-% Margins, etc, within the check itself
120-% -------------------------------------
121-
122-/LeftMargin {0.2 inch} def
123-/RightMargin {0.4 inch} def
124-/TopMargin {0.2 inch} def
125-
126-% Check feature placement
127-% -----------------------
128-% (relative to bottom left corner of check)
129-
130-/MemoLineHeight {0.25} def
131-/SignatureLineHeight {0.25} def
132-/AmountLineHeight {0.50} def
133-/PayeeLineHeight {0.60} def
134-/BankInfoHeight {0.45} def
135-/DateLineHeight {0.75} def
136-
137-%%%%%%%%%%%%%%%%%%%%%%%%%%
138-% Check Blank Dimensions %
139-% (The Check Blank File) %
140-%%%%%%%%%%%%%%%%%%%%%%%%%%
141-
142-% Information about how the checks are laid out on the page
143-% ---------------------------------------------------------
144-
145-/CheckHeight {2.85 inch} def
146-/CheckWidth {5.96 inch} def
147-/CheckHorOffset {2.54 inch} def % how far are checks from left edge of sheet
148-/CheckVerOffset {2.48 inch} def % how far is bottom check from bottom of sheet
149-/ChecksPerPage {3} def % How many checks are on the sheet? (vertical)
150-
151-%%%%%%%%%%%%%%%%%%%%%%%
152-% Global Setup Values %
153-%%%%%%%%%%%%%%%%%%%%%%%
154-
155-% MICR Font
156-% ---------
157-% For the MICR font, SIZE MATTERS! Make sure you have the right point
158-% size for the particular MICR font you're using. Most (including
159-% GnuMICR) are correct at 12 pts, but READ THE DOCS THAT CAME WITH
160-% THE FONT! :)
161-
162-/MICRFontName /GnuMICR def
163-/MICRFontSize 12 def
164-
165-% MICR Symbol Mapping
166-% -------------------
167-% Maps which characters show which MICR symbols in the font you're using
168-% Approximate representations of these symbols, with names, below:
169-% |: = TransitNumberSymbol
170-% / = Amount
171-% P = OnUs
172-% - = Dash
173-
174-/TransitSymbol (A) def
175-/OnUsSymbol (C) def
176-/AmountSymbol (B) def
177-/DashSymbol (D) def
178-
179-% MICR Line placement
180-% -------------------
181-% This should be smack in the middle of the tolerance band...
182-% Tweaks are accomplished by the user in the Global section
183-
184-/MICRLineHeight {0.25 inch} def
185-
186-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187-% End of user entered information %
188-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189-
190-% Other Constants:
191-
192-% Size of the rectangular box for the amount (digits)
193-/AmountBoxWidth {1 inch} def
194-/AmountBoxHeight {0.25 inch} def
195-
196-/LineWidth {0.3} def
197-
198-% Max number of digits in check number, and allocate string
199-/CheckNumDigits 4 def
200-/CheckNumberString CheckNumber log floor 1 add cvi string def
201-
202-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203-% Helpful Printing Routines %
204-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205-
206-% Shows a line, then does a "carriage return / line feed"
207-% But only if the string exists (more than 0 chars)
208-% (How do we get the current font size (height)?)
209-
210-/ShowAndCR {
211- % A couple copies of the string (now 3 on stack)
212- dup dup
213- length 0 gt { % First copy
214- show % Second copy
215- stringwidth pop neg 0 rmoveto % Third copy & move back
216- neg 0 exch rmoveto % line down
217- } if
218-} def
219-
220-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221-% Feature Printing Routines %
222-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223-
224-/DrawMemoLine {
225- LeftMargin MemoLineHeight CheckHeight mul moveto
226- 2.5 inch 0 inch rlineto
227- -2.5 inch 0 inch rmoveto
228- 0 2 rmoveto
229- (for) show
230-} def
231-
232-/DrawSignatureLine { % Expects height of signature line
233- % and right edge of check for
234- % beginning position
235-
236- CheckWidth SignatureLineHeight CheckHeight mul moveto
237- RightMargin neg 0 rmoveto
238- -2.5 inch 0 rmoveto
239- 2.5 inch 0 inch rlineto
240-
241-} def
242-
243-/DrawAmountLine {
244- CheckWidth AmountLineHeight CheckHeight mul moveto
245- RightMargin neg 0 rmoveto
246- (DOLLARS) stringwidth pop neg 0 rmoveto
247- (DOLLARS) show
248- (DOLLARS) stringwidth pop neg 0 rmoveto
249- -2 0 rmoveto
250- LeftMargin AmountLineHeight CheckHeight mul lineto
251-} def
252-
253-/DrawAccountHolderInfo {
254- LeftMargin CheckHeight moveto
255- 0 TopMargin neg rmoveto
256- 0 StandardFontSize neg rmoveto
257-
258- StandardFontSize Name1 ShowAndCR
259- StandardFontSize Name2 ShowAndCR
260-
261- StandardFontName findfont
262- StandardFontSize 1 sub scalefont
263- setfont
264-
265- StandardFontSize 1 sub Address1 ShowAndCR
266- StandardFontSize 1 sub Address2 ShowAndCR
267- StandardFontSize 1 sub CityStateZip ShowAndCR
268- StandardFontSize 1 sub PhoneNumber ShowAndCR
269-
270- StandardFontName findfont
271- StandardFontSize 1 add scalefont
272- setfont
273-} def
274-
275-/DrawDateLine {
276- 0.6 CheckWidth mul DateLineHeight CheckHeight mul moveto
277- (Date) show
278- 1 inch 0 rlineto
279-} def
280-
281-/DrawBankInfo {
282- LeftMargin BankInfoHeight CheckHeight mul moveto
283-
284- StandardFontSize BankName ShowAndCR
285-
286- StandardFontName findfont
287- StandardFontSize 1 sub scalefont
288- setfont
289-
290- StandardFontSize 1 sub BankAddr1 ShowAndCR
291- StandardFontSize 1 sub BankAddr2 ShowAndCR
292- StandardFontSize 1 sub BankCityStateZip ShowAndCR
293-
294- StandardFontName findfont
295- StandardFontSize 1 add scalefont
296- setfont
297-} def
298-
299-/DrawPayeeLine {
300-
301- LeftMargin PayeeLineHeight CheckHeight mul moveto
302- (ORDER OF) show
303- (ORDER OF) stringwidth pop neg StandardFontSize rmoveto
304- (PAY TO THE) show
305- 0 StandardFontSize neg rmoveto
306- 4 0 rmoveto
307- currentpoint mark
308-
309- CheckWidth PayeeLineHeight CheckHeight mul moveto
310- RightMargin neg 0 rmoveto
311- AmountBoxWidth neg 0 rmoveto
312-
313- 0 AmountBoxHeight rlineto
314- AmountBoxWidth 0 rlineto
315- 0 AmountBoxHeight neg rlineto
316- AmountBoxWidth neg 0 rlineto
317-
318- -4 0 rmoveto
319-
320- /Helvetica-Bold findfont
321- 14 scalefont
322- setfont
323-
324- ($) stringwidth pop neg 0 rmoveto
325- ($) show
326- ($) stringwidth pop neg 0 rmoveto
327-
328- -4 0 rmoveto
329- cleartomark
330- lineto
331-
332- StandardFontName findfont
333- StandardFontSize scalefont
334- setfont
335-
336-} def
337-
338-/DrawMICR {
339- % 0.25 high, 5.6875 from right edge should be in the middle
340- % of the tolerance band
341- CheckWidth 0.25 inch moveto
342- -5.6875 inch 0 inch rmoveto
343- MICRHorTweak MICRVerTweak rmoveto
344-
345- save
346- MICRFontName findfont
347- MICRFontSize scalefont
348- setfont
349- % If wide check, check number goes on the left
350- % with OnUS symbols around it
351- % so pad out the zeros, move back that far + space
352- CheckWidth 8.00 inch ge {
353- (0) stringwidth pop neg
354- CheckNumDigits mul
355- 3 add %2 OnUs symbols + space
356- 0 rmoveto
357- OnUsSymbol show
358- CheckNumDigits CheckNumberString length sub
359- { (0) show } repeat
360- CheckNumberString show
361- OnUsSymbol show
362- ( ) show
363- } if
364- TransitSymbol show
365- RoutingNumber show
366- TransitSymbol show
367- ( ) show
368- % Pad with spaces if acct number is short
369- 12 AccountNumber length sub {( ) show} repeat
370- AccountNumber show
371- OnUsSymbol show
372- ( ) show
373- % If we have a short check, check number goes here
374- CheckWidth 8.00 inch lt {
375- % Same deal, pad w/ 0s if short check number
376- CheckNumDigits CheckNumberString length sub
377- { (0) show } repeat
378- CheckNumberString show
379- } if
380- restore
381-} def
382-
383-/DrawCheckNumber {
384- CheckWidth CheckHeight moveto
385- RightMargin neg TopMargin neg rmoveto
386- CheckNumFont findfont
387- CheckNumSize scalefont
388- setfont
389-
390- CheckNumberString stringwidth pop neg 0 rmoveto
391- 0 -14 rmoveto
392- CheckNumberString show
393-
394- StandardFontName findfont
395- StandardFontSize scalefont
396- setfont
397-} def
398-
399-/DrawFraction {
400- 0.6 CheckWidth mul CheckHeight moveto
401- 0 TopMargin neg rmoveto
402- 0 StandardFontSize neg rmoveto
403- Fraction show
404-} def
405-
406-/DrawStub {
407- CheckHorOffset 2 inch ge {
408- save
409- newpath
410- CheckHorOffset neg 0 translate
411- StandardFontName findfont
412- StandardFontSize 1 sub scalefont
413- setfont
414- /StubSpacing {CheckHeight 6 div} def
415- CheckHorOffset 2 div StubSpacing 5 mul moveto
416- CheckNumberString show
417- 0.3 inch StubSpacing 4 mul moveto
418- (Date ) show
419- CheckHorOffset 0.3 inch sub StubSpacing 4 mul lineto
420- 0.3 inch StubSpacing 3 mul moveto
421- (Payee ) show
422- CheckHorOffset 0.3 inch sub StubSpacing 3 mul lineto
423- 0.3 inch StubSpacing 2 mul moveto
424- (Amount ) show
425- CheckHorOffset 0.3 inch sub StubSpacing 2 mul lineto
426- 0.3 inch StubSpacing 1 mul moveto
427- (Memo ) show
428- CheckHorOffset 0.3 inch sub StubSpacing 1 mul lineto
429- stroke
430- restore
431- } if
432-} def
433-
434-/DrawVOID {
435- save
436- StandardFontName findfont
437- 50 scalefont
438- setfont
439- newpath
440- CheckWidth 2 div 1 inch moveto
441- 30 rotate
442- (V O I D) stringwidth pop 0 moveto
443- (V O I D) true charpath
444- stroke
445- restore
446-} def
447-
448-/DrawCheck {
449-
450- % Convert CheckNumber integer to a string
451- CheckNumber CheckNumberString cvs
452- PrintCheckBody {
453- DrawBankInfo
454- DrawAccountHolderInfo
455- DrawMemoLine
456- DrawSignatureLine
457- DrawAmountLine
458- DrawPayeeLine
459- DrawCheckNumber
460- DrawFraction
461- DrawDateLine
462- DrawStub
463- } if
464-
465- PrintMICRLine {
466- DrawMICR
467- } if
468-
469- PrintVOID {
470- % Draw border around check, and print "VOID" for testing
471- 0 0 moveto
472- CheckWidth 0 lineto
473- CheckWidth CheckHeight lineto
474- 0 CheckHeight lineto
475- 0 0 lineto
476-
477- DrawVOID
478- } if
479-
480-} def
481-
482-
483-/CurrentPage 1 def
484-
485-NumPages -1 1 {
486- /CheckNumber CheckNumber ChecksPerPage add def
487- CheckHorOffset CheckVerOffset translate
488-
489- StandardFontName findfont
490- StandardFontSize scalefont
491- setfont
492-
493- LineWidth setlinewidth
494-
495- % Loop through printing checks, starting with the bottom one
496-
497- ChecksPerPage -1 1 {
498- /CheckNumber CheckNumber 1 sub def
499- newpath
500- DrawCheck
501- stroke
502- 0 CheckHeight translate
503- } for
504-
505- showpage
506- /CheckNumber CheckNumber ChecksPerPage add def
507- /CurrentPage CurrentPage 1 add def
508-
509-} for
510-

Built with git-ssb-web