git ssb

0+

cel / freecheck



Commit 0e146f91b23a1bc9553cedbc2b2908c3912a95b9

commit from v0.2 tarball

Caleb Maclennan committed on 3/10/2014, 9:04:44 PM
Parent: 6100c2a5d781d1ac261195db53af7fa6685e1e10

Files changed

AUTHORSchanged
ChangeLogchanged
example_check.pschanged
freecheck.cfgchanged
README-CGIadded
freecheck.pldeleted
example_check.ps.newadded
freecheckadded
freecheck.cgiadded
AUTHORSView
@@ -1,4 +1,3 @@
1-freecheck is written by:
1 +FreeCheck is written by:
22
3-Eric Sandeen <eric_sandeen@bigfoot.com>
4-
3 + Eric Sandeen <eric_sandeen@bigfoot.com>
ChangeLogView
@@ -1,2 +1,29 @@
1 ++ added
2 +- removed
3 +* bug fix
4 +% change
5 +
6 +Version 0.2, July 22, 2000
7 + + Added error checking for nonexistant acct/style/blank
8 + + Added options to show available accts/styles/blanks
9 + + Added centimeter ("cm") def - dims can now be in cm
10 + % Changed style section definition a bit (no "CheckHeight mul")
11 + + Added --cgi option to pass config from another script (cgi)
12 + + Added simple cgi script to accomplish above interface...
13 + + cgi script uses cookies to save parameters
14 + * Strip whitespace from end of lines in config file
15 + + Replace dash ("-") in account number with dash symbol, if entered
16 + + Made number of digits in check number configurable (leading 0's)
17 + Cleaned up PostScript a bit:
18 + % Prints acct number left of routing number for large checks
19 + (and changed logic around check number string a bit)
20 + - Removed commented-out sections
21 + * Only prints stub when check body is printed
22 + * Only prints check border lines if --test requested
23 +
124 Version 0.1, July 16, 2000
225 First semi-distributed version
26 +
27 +
28 +
29 +
example_check.psView
@@ -1,182 +1,182 @@
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 CheckHeight mul} def
131-/SignatureLineHeight {0.25 CheckHeight mul} def
132-/AmountLineHeight {0.50 CheckHeight mul} def
133-/PayeeLineHeight {0.60 CheckHeight mul} def
134-/BankInfoHeight {0.45 CheckHeight mul} def
135-/DateLineHeight {0.75 CheckHeight mul} 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
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 +%---------------
17824
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 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 +
179179 % MICR Line placement
180180 % -------------------
181181 % This should be smack in the middle of the tolerance band...
182182 % Tweaks are accomplished by the user in the Global section
@@ -196,9 +196,9 @@
196196 /LineWidth {0.3} def
197197
198198 % Max number of digits in check number, and allocate string
199199 /CheckNumDigits 4 def
200-/CheckNumberString CheckNumDigits string def
200 +/CheckNumberString CheckNumber log floor 1 add cvi string def
201201
202202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203203 % Helpful Printing Routines %
204204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -221,9 +221,9 @@
221221 % Feature Printing Routines %
222222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223223
224224 /DrawMemoLine {
225- LeftMargin MemoLineHeight moveto
225 + LeftMargin MemoLineHeight CheckHeight mul moveto
226226 2.5 inch 0 inch rlineto
227227 -2.5 inch 0 inch rmoveto
228228 0 2 rmoveto
229229 (for) show
@@ -232,114 +232,82 @@
232232 /DrawSignatureLine { % Expects height of signature line
233233 % and right edge of check for
234234 % beginning position
235235
236- CheckWidth SignatureLineHeight moveto
236 + CheckWidth SignatureLineHeight CheckHeight mul moveto
237237 RightMargin neg 0 rmoveto
238238 -2.5 inch 0 rmoveto
239239 2.5 inch 0 inch rlineto
240240
241241 } def
242242
243243 /DrawAmountLine {
244- CheckWidth AmountLineHeight moveto
244 + CheckWidth AmountLineHeight CheckHeight mul moveto
245245 RightMargin neg 0 rmoveto
246246 (DOLLARS) stringwidth pop neg 0 rmoveto
247247 (DOLLARS) show
248248 (DOLLARS) stringwidth pop neg 0 rmoveto
249249 -2 0 rmoveto
250- LeftMargin AmountLineHeight lineto
250 + LeftMargin AmountLineHeight CheckHeight mul lineto
251251 } def
252252
253253 /DrawAccountHolderInfo {
254254 LeftMargin CheckHeight moveto
255255 0 TopMargin neg rmoveto
256256 0 StandardFontSize neg rmoveto
257257
258-
259258 StandardFontSize Name1 ShowAndCR
260- %Name1 show
261- %Name1 stringwidth pop neg StandardFontSize neg rmoveto
262-
263-
264259 StandardFontSize Name2 ShowAndCR
265- % Show Name2 only if present
266- %Name2 length 0 gt {
267- % Name2 show
268- % Name2 stringwidth pop neg StandardFontSize neg rmoveto
269- %} if
270260
271261 StandardFontName findfont
272262 StandardFontSize 1 sub scalefont
273263 setfont
274264
275265 StandardFontSize 1 sub Address1 ShowAndCR
276- %Address1 stringwidth pop neg StandardFontSize neg rmoveto
266 + StandardFontSize 1 sub Address2 ShowAndCR
267 + StandardFontSize 1 sub CityStateZip ShowAndCR
268 + StandardFontSize 1 sub PhoneNumber ShowAndCR
277269
278- % Show Address2 only if present
279- Address2 length 0 gt {
280- Address2 show
281- Address2 stringwidth pop neg StandardFontSize neg rmoveto
282- } if
283-
284- CityStateZip show
285- CityStateZip stringwidth pop neg StandardFontSize neg rmoveto
286-
287- % Show PhoneNumber only if present
288- PhoneNumber length 0 gt {
289- PhoneNumber show
290- PhoneNumber stringwidth pop neg StandardFontSize neg rmoveto
291- } if
292-
293270 StandardFontName findfont
294271 StandardFontSize 1 add scalefont
295272 setfont
296273 } def
297274
298275 /DrawDateLine {
299- 0.6 CheckWidth mul DateLineHeight moveto
276 + 0.6 CheckWidth mul DateLineHeight CheckHeight mul moveto
300277 (Date) show
301278 1 inch 0 rlineto
302279 } def
303280
304281 /DrawBankInfo {
305- LeftMargin BankInfoHeight moveto
282 + LeftMargin BankInfoHeight CheckHeight mul moveto
306283
307- BankName show
308- BankName stringwidth pop neg StandardFontSize neg rmoveto
284 + StandardFontSize BankName ShowAndCR
309285
310286 StandardFontName findfont
311287 StandardFontSize 1 sub scalefont
312288 setfont
313289
314- BankAddr1 show
315- BankAddr1 stringwidth pop neg StandardFontSize neg rmoveto
290 + StandardFontSize 1 sub BankAddr1 ShowAndCR
291 + StandardFontSize 1 sub BankAddr2 ShowAndCR
292 + StandardFontSize 1 sub BankCityStateZip ShowAndCR
316293
317- % Show Addr2 only if present
318- BankAddr2 length 0 gt {
319- BankAddr2 show
320- BankAddr2 stringwidth pop neg StandardFontSize neg rmoveto
321- } if
322-
323- BankCityStateZip show
324- BankCityStateZip stringwidth pop neg StandardFontSize neg rmoveto
325-
326294 StandardFontName findfont
327295 StandardFontSize 1 add scalefont
328296 setfont
329297 } def
330298
331299 /DrawPayeeLine {
332300
333- LeftMargin PayeeLineHeight moveto
301 + LeftMargin PayeeLineHeight CheckHeight mul moveto
334302 (ORDER OF) show
335303 (ORDER OF) stringwidth pop neg StandardFontSize rmoveto
336304 (PAY TO THE) show
337305 0 StandardFontSize neg rmoveto
338306 4 0 rmoveto
339307 currentpoint mark
340308
341- CheckWidth PayeeLineHeight moveto
309 + CheckWidth PayeeLineHeight CheckHeight mul moveto
342310 RightMargin neg 0 rmoveto
343311 AmountBoxWidth neg 0 rmoveto
344312
345313 0 AmountBoxHeight rlineto
@@ -377,8 +345,23 @@
377345 save
378346 MICRFontName findfont
379347 MICRFontSize scalefont
380348 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
381364 TransitSymbol show
382365 RoutingNumber show
383366 TransitSymbol show
384367 ( ) show
@@ -386,12 +369,15 @@
386369 12 AccountNumber length sub {( ) show} repeat
387370 AccountNumber show
388371 OnUsSymbol show
389372 ( ) show
390- % Same deal, pad w/ 0s if short check number
391- CheckNumDigits 1 sub -1 1
392- {CheckNumberString exch get 0 eq {(0) show} if } for
393- CheckNumberString 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
394380 restore
395381 } def
396382
397383 /DrawCheckNumber {
@@ -451,26 +437,20 @@
451437 50 scalefont
452438 setfont
453439 newpath
454440 CheckWidth 2 div 1 inch moveto
455- 30 rotate
456- (V O I D) stringwidth pop 0 moveto
457- (V O I D) true charpath
441 +% 30 rotate
442 +% (V O I D) stringwidth pop 0 moveto
443 +% (V O I D) true charpath
458444 stroke
459445 restore
460446 } def
461447
462448 /DrawCheck {
463- % Temporarily draw boxes around the checks
464- 0 0 moveto
465- CheckWidth 0 lineto
466- CheckWidth CheckHeight lineto
467- 0 CheckHeight lineto
468- 0 0 lineto
469449
470450 % Convert CheckNumber integer to a string
451 + CheckNumber CheckNumberString cvs
471452 PrintCheckBody {
472- CheckNumber CheckNumberString cvs
473453 DrawBankInfo
474454 DrawAccountHolderInfo
475455 DrawMemoLine
476456 DrawSignatureLine
@@ -478,15 +458,23 @@
478458 DrawPayeeLine
479459 DrawCheckNumber
480460 DrawFraction
481461 DrawDateLine
462 + DrawStub
482463 } if
483464
484465 PrintMICRLine {
485466 DrawMICR
486467 } if
487468
488469 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 +
489477 DrawVOID
490478 } if
491479
492480 } def
@@ -508,12 +496,9 @@
508496
509497 ChecksPerPage -1 1 {
510498 /CheckNumber CheckNumber 1 sub def
511499 newpath
512-
513500 DrawCheck
514- DrawStub % But only if there is room
515-
516501 stroke
517502 0 CheckHeight translate
518503 } for
519504
@@ -521,4 +506,5 @@
521506 /CheckNumber CheckNumber ChecksPerPage add def
522507 /CurrentPage CurrentPage 1 add def
523508
524509 } for
510 +
freecheck.cfgView
@@ -25,9 +25,9 @@
2525 # Some values (such as font names) are case sensitive
2626 # Others, such as address strings, will print in whatever case you enter them
2727 # Values may be multiple words
2828 # Values which represent dimensions may be bare numbers (which results in
29-# "points," or 1/72 of an inch) or followed by "inch" which should be
29 +# "points," or 1/72 of an inch) or followed by "inch" or "cm" which should be
3030 # self-explanatory.
3131
3232 # Each section contains comments showing all required key-value pairs, and
3333 # examples of assignments.
@@ -72,10 +72,10 @@
7272 [Global]
7373 MICRFontName = GnuMICR
7474 MICRFontSize = 12
7575 TransitSymbol = A
76-OnUsSymbol = C
77-AmountSymbol = B
76 +AmountSymbol = B
77 +OnUsSymbol = C
7878 DashSymbol = D
7979 MICRVerTweak = 0
8080 MICRHorTweak = 0
8181
@@ -122,12 +122,12 @@
122122 # AccountNumber = 1234567890 # Middle MICR numbers
123123 # Fraction = 12345/67890 # Fraction at top of check
124124
125125 [Account Sample]
126 +CheckNumber = 100
126127 PrintCheckBody = true
127-CheckNumber = 100
128-PrintMICRLine = true
129-NumPages = 2
128 +PrintMICRLine = true
129 +NumPages = 1
130130 Name1 = JOHN SMITH
131131 Name2 = MARY SMITH
132132 Address1 = 1234 Main Street
133133 Address2 =
@@ -152,36 +152,38 @@
152152 # addresses, etc)
153153 # StandardFontName = AvantGarde-Book
154154 # StandardFontSize = 9
155155
156 +# Number of digits in the check number (adds leading 0s if necessary)
157 +# CheckNumDigits = 4
158 +
156159 # This is NOT THE MICR FONT! It is the big check number on top right
157160 # CheckNumFont = Helvetica-Bold
158161 # CheckNumSize = 14
159162
160163 # Check feature placement
161164 # -----------------------
162165 # (relative to bottom of check)
163-# Currently implemented as multiples of the check height
164-# Could be absolute (inches) but would break across different
165-# types of check blanks
166-# MemoLineHeight = 0.25 CheckHeight mul
167-# SignatureLineHeight = 0.25 CheckHeight mul
168-# BankInfoHeight = 0.45 CheckHeight mul
169-# AmountLineHeight = 0.50 CheckHeight mul
170-# PayeeLineHeight = 0.60 CheckHeight mul
171-# DateLineHeight = 0.75 CheckHeight mul
166 +# Currently implemented as fraction of the check height
167 +# MemoLineHeight = 0.25
168 +# SignatureLineHeight = 0.25
169 +# BankInfoHeight = 0.45
170 +# AmountLineHeight = 0.50
171 +# PayeeLineHeight = 0.60
172 +# DateLineHeight = 0.75
172173
173174 [Style Normal]
174175 StandardFontName = AvantGarde-Book
175176 StandardFontSize = 9
177 +CheckNumDigits = 4
176178 CheckNumFont = Helvetica-Bold
177179 CheckNumSize = 14
178-MemoLineHeight = 0.25 CheckHeight mul
179-SignatureLineHeight = 0.25 CheckHeight mul
180-BankInfoHeight = 0.45 CheckHeight mul
181-AmountLineHeight = 0.50 CheckHeight mul
182-PayeeLineHeight = 0.60 CheckHeight mul
183-DateLineHeight = 0.75 CheckHeight mul
180 +MemoLineHeight = 0.25
181 +SignatureLineHeight = 0.25
182 +BankInfoHeight = 0.45
183 +AmountLineHeight = 0.50
184 +PayeeLineHeight = 0.60
185 +DateLineHeight = 0.75
184186
185187 ################
186188 # CHECK BLANKS #
187189 ################
README-CGIView
@@ -1,0 +1,13 @@
1 +The freecheck.cgi script is a simple web interface to the freecheck application.
2 +
3 +To use it, place freecheck.cgi, freecheck, and freecheck.cfg in a directory
4 +from which your web server can execute scripts (cgi-bin/).
5 +
6 +You may need to edit the script just a bit - if you want to use the PDF output
7 +feature, edit the $GS variable at the top of freecheck.cgi to point to your
8 +GhostScript executable.
9 +
10 +For some reason, Netscape (and Mozilla) under Linu don't auto-load the returned
11 +PDF or PS file, even if you have an application set up - it always want to save
12 +"freecheck.cgi" - I don't know why. You can just rename the file... if someone
13 +can figure this out, please let me know. :-)
freecheck.plView
@@ -1,640 +1,0 @@
1-#!/usr/bin/perl
2-
3-#---------------
4-#
5-# FreeCheck - a free check printing application released
6-# under the GNU General Public Licene.
7-#
8-# Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
9-#
10-# This program is free software; you can redistribute it and/or modify
11-# it under the terms of the GNU General Public License as published by
12-# the Free Software Foundation; either version 2 of the License, or
13-# (at your option) any later version.
14-#
15-# This program is distributed in the hope that it will be useful,
16-# but WITHOUT ANY WARRANTY; without even the implied warranty of
17-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18-# GNU General Public License for more details.
19-#
20-# You should have received a copy of the GNU General Public License
21-# along with this program; if not, write to the Free Software
22-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23-#
24-#---------------
25-
26-$ConfigFile = "freecheck.cfg";
27-
28-# Some defaults...
29-$opt_account = "sample";
30-$opt_checktype = "MVG3001";
31-$opt_checkstyle = "normal";
32-
33-use Getopt::Long;
34-#use Carp;
35-
36-#use File::Slurp;
37-
38-# This tells us how to format the strings from the cfg file
39-# so we can print it as a PostScript definition
40-# The key read will replace "value" for each of these
41-# Strings are enclosed in parentheses (String) (Foobar)
42-# Fonts are preceded by a "/" /FontName /Arial
43-# Digits are fine as they are Digit 123
44-# Booleans are fine too Bool true
45-# But to be safe, do digits and bools as subroutines:
46-# Subroutines are in {} {subr} {3 mul}
47-
48-%Formats = qw(
49- # Globals
50- MICRFontName /value
51- MICRFontSize {value}
52- TransitSymbol (value)
53- OnUsSymbol (value)
54- AmountSymbol (value)
55- DashSymbol (value)
56- MICRVerTweak {value}
57- MICRHorTweak {value}
58- # Account
59- CheckNumber {value}
60- PrintCheckBody {value}
61- PrintMICRLine {value}
62- NumPages {value}
63- Name1 (value)
64- Name2 (value)
65- Address1 (value)
66- Address2 (value)
67- CityStateZip (value)
68- PhoneNumber (value)
69- BankName (value)
70- BankAddr1 (value)
71- BankAddr2 (value)
72- BankCityStateZip (value)
73- RoutingNumber (value)
74- AccountNumber (value)
75- Fraction (value)
76- PrintVOID {value}
77- # Styles
78- StandardFontName /value
79- StandardFontSize {value}
80- CheckNumFont /value
81- CheckNumSize {value}
82- MemoLineHeight {value}
83- SignatureLineHeight {value}
84- BankInfoHeight {value}
85- AmountLineHeight {value}
86- PayeeLineHeight {value}
87- DateLineHeight {value}
88- # Check Blank Types
89- CheckHeight {value}
90- CheckWidth {value}
91- CheckHorOffset {value}
92- CheckVerOffset {value}
93- ChecksPerPage {value}
94- LeftMargin {value}
95- RightMargin {value}
96- TopMargin {value}
97- );
98-
99-# Parse command line options and deal with them:
100-
101-GetOptions ("account:s", # Account definition file
102- "checknum:i", # Check number optional (overrides acct file)
103- "pages:i", # Number of pages to print
104- "checkstyle:s", # Check style (defaults to "normal_style.ps"
105- "checktype:s", # Check blank definition
106- "nomicr", # Prevents MICR line from printing (body only)
107- "nobody", # Prevents body from printing (MICR line only)
108- "test", # Don't increment check no. and print VOID
109- "help")
110-
111-or Show_Usage();
112-
113-if ($opt_help) {
114- Show_Usage();
115-}
116-
117-# Pull the config file into a string...
118-$config_file = read_file($ConfigFile);
119-
120-# Go through the config and fill up a hash with PostScript defines...
121-Parse_Config($config_file);
122-
123-# Overwrite anything we got from the config file with what was on the
124-# Command Line (if anything...)
125-
126-if ($opt_checknum) {
127- $Definitions{"CheckNumber"} = $opt_checknum;
128-}
129-
130-if ($opt_pages) {
131- $Definitions{"NumPages"} = $opt_pages;
132-}
133-
134-if ($opt_nomicr) {
135- $Definitions{"PrintMICRLine"} = "false";
136-}
137-
138-if ($opt_nobody) {
139- $Definitions{"PrintCheckBody"} = "false";
140-}
141-
142-# This probably isn't in the config file (although it might be...)
143-# so cover both possibilites (true/false)
144-if ($opt_test) {
145- $Definitions{"PrintVOID"} = "true";
146-} else {
147- $Definitions{"PrintVOID"} = "false";
148-}
149-
150-# Print PostScript
151-
152-# Initial stuff:
153-
154-print "%!\n";
155-print "/inch {72 mul} def\n";
156-
157-# Go through $Definitions and print them out PostScript-Like
158-Print_Defs();
159-
160-# Then print the main body
161-Print_Body();
162-
163-# Update the config file with the new check number, if it's not just a test
164-if (!$opt_test) {
165- $next_check_number = $Definitions{"CheckNumber"}
166- + ($Definitions{"NumPages"} * $Definitions{"ChecksPerPage"});
167-
168- $config_file = Replace_Val($config_file, "Account", $opt_account,
169- "CheckNumber", $next_check_number);
170- write_file ("freecheck.cfg", $config_file);
171-}
172-
173-###############
174-# Subroutines #
175-###############
176-
177-# read_file and write_file shamelessly stolen from the File::Slurp module
178-# Short enough, and I didn't want to require a non-standard module
179-
180-sub read_file
181-{
182- my ($file) = @_;
183-
184- local(*F);
185- my $r;
186- my (@r);
187-
188- open(F, "<$file") || die "open $file: $!";
189- @r = <F>;
190- close(F);
191-
192- return @r if wantarray;
193- return join("",@r);
194-}
195-
196-sub write_file
197-{
198- my ($f, @data) = @_;
199-
200- local(*F);
201-
202- open(F, ">$f") || die "open >$f: $!";
203- (print F @data) || die "write $f: $!";
204- close(F) || die "close $f: $!";
205- return 1;
206-}
207-
208-
209-sub Parse_Config {
210- local ($config_file) = ($_[0]);
211- # Find each section we're looking for...
212- while ($config_file =~ /^\[\s*(
213- Global |
214- Account\s+${opt_account} |
215- Style\s+${opt_checkstyle} |
216- CheckBlank\s+${opt_checktype}
217- )\s*\]/xmgci) {
218- # and get the lines under it one by one
219- while ($config_file =~ /(^.+$)/mgc) {
220- $line = $+;
221- # If this line is a comment, skip it
222- if ($line =~ /^#/) {
223- next;
224- }
225- # If the line we just found is a new section..."[...]"
226- if ($line =~ /\[.+\]/) {
227- # and it is another section we're looking for
228- # Grab the next line, and keep going
229- if ($line =~ /\[\s*(
230- Global |
231- Account\s+${opt_account} |
232- Style\s+${opt_checkstyle} |
233- CheckBlank\s+${opt_checktype}
234- )\s*]/xi) {
235- # Grab the next line, and keep going
236- next;
237- } else {
238- # Not a section we need, so break out
239- # of the loop
240- last;
241- }
242- }
243-
244- ($key, $val) = split (/\s*=\s*/,$line);
245- $Definitions{$key} = $val;
246- } # line-by-line while
247- } # section match conditional
248-}
249-
250-sub Replace_Val {
251- local ($string, $section, $name, $key, $value) =
252- ($_[0], $_[1], $_[2], $_[3], $_[4]);
253- # We want to get "[section name] ... key = value" and replace it
254- # with the new value.
255-
256- # s - "." matches ANYTHING including newline
257- # m - ^ and $ match after and before any newline
258- # in this case, ".+?" means the minimum number of <anything> i.e. end
259- # when we find the first instance of $key after [section name]
260- $string =~
261- s/(^\[\s*$section\s+$name\s*\].+?^${key}\s*=\s*).*?$/$+$value/smi;
262- $string;
263-}
264-
265-sub Show_Usage {
266- print "\nFreeCheck v. 0.1 - a Free Check printing Utility\n\n";
267- print "Usage: freecheck <options>:\n";
268- print "\n";
269- print "options:\n";
270- print " --account <filename> account to use (default \"$opt_account\")\n";
271- print " --checknum <integer> starting check number (overrides cfg)\n";
272- print " --pages <integer> number of pages to print (overrides cfg)\n";
273- print " --checkstyle <filename> check style to use (default \"$opt_checkstyle\")\n";
274- print " --checktype <filename> blank check type to use (default \"$opt_checktype\")\n";
275- print " --nomicr print check body only, no MICR line\n";
276- print " --nobody print MICR line only, no check body\n";
277- print " --help print this message\n";
278- print " --test print but don't increment check number\n";
279- print " and print VOID on the check\n";
280- print "\nconfig file \"freecheck.cfg\" must be in the same directory,\n";
281- print "as the freecheck executable (this will change in the future...)\n";
282- die "\n";
283-}
284-
285-sub Print_Defs {
286- # Go through each def in the hash table, and print according to the
287- # formatting hash
288- while ( ($key, $val) = each (%Definitions) ) {
289- print "/$key\t";
290- $_ = $Formats{$key};
291- s/value/$val/;
292- print;
293- print " def\n";
294- }
295-}
296-
297-sub Print_Body {
298-
299-# This is the main body of the postscript file, that acts on all of the
300-# definitions we got from the config file.
301-
302-print '
303- % Other Constants:
304-
305- % Size of the rectangular box for the amount (digits)
306- /AmountBoxWidth {1 inch} def
307- /AmountBoxHeight {0.25 inch} def
308-
309- /LineWidth {0.3} def
310-
311- % Max number of digits in check number, and allocate string
312- /CheckNumDigits 4 def
313- /CheckNumberString CheckNumDigits string def
314-
315- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316- % Helpful Printing Routines %
317- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318-
319- % Shows a line, then does a "carriage return / line feed"
320- % But only if the string exists (more than 0 chars)
321- % (How do we get the current font size (height)?)
322-
323- /ShowAndCR {
324- % A couple copies of the string (now 3 on stack)
325- dup dup
326- length 0 gt { % First copy
327- show % Second copy
328- stringwidth pop neg 0 rmoveto % Third copy & move back
329- neg 0 exch rmoveto % line down
330- } if
331- } def
332-
333- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334- % Feature Printing Routines %
335- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336-
337- /DrawMemoLine {
338- LeftMargin MemoLineHeight moveto
339- 2.5 inch 0 inch rlineto
340- -2.5 inch 0 inch rmoveto
341- 0 2 rmoveto
342- (for) show
343- } def
344-
345- /DrawSignatureLine { % Expects height of signature line
346- % and right edge of check for
347- % beginning position
348-
349- CheckWidth SignatureLineHeight moveto
350- RightMargin neg 0 rmoveto
351- -2.5 inch 0 rmoveto
352- 2.5 inch 0 inch rlineto
353-
354- } def
355-
356- /DrawAmountLine {
357- CheckWidth AmountLineHeight moveto
358- RightMargin neg 0 rmoveto
359- (DOLLARS) stringwidth pop neg 0 rmoveto
360- (DOLLARS) show
361- (DOLLARS) stringwidth pop neg 0 rmoveto
362- -2 0 rmoveto
363- LeftMargin AmountLineHeight lineto
364- } def
365-
366- /DrawAccountHolderInfo {
367- LeftMargin CheckHeight moveto
368- 0 TopMargin neg rmoveto
369- 0 StandardFontSize neg rmoveto
370-
371-
372- StandardFontSize Name1 ShowAndCR
373- %Name1 show
374- %Name1 stringwidth pop neg StandardFontSize neg rmoveto
375-
376-
377- StandardFontSize Name2 ShowAndCR
378- % Show Name2 only if present
379- %Name2 length 0 gt {
380- % Name2 show
381- % Name2 stringwidth pop neg StandardFontSize neg rmoveto
382- %} if
383-
384- StandardFontName findfont
385- StandardFontSize 1 sub scalefont
386- setfont
387-
388- StandardFontSize 1 sub Address1 ShowAndCR
389- %Address1 stringwidth pop neg StandardFontSize neg rmoveto
390-
391- % Show Address2 only if present
392- Address2 length 0 gt {
393- Address2 show
394- Address2 stringwidth pop neg StandardFontSize neg rmoveto
395- } if
396-
397- CityStateZip show
398- CityStateZip stringwidth pop neg StandardFontSize neg rmoveto
399-
400- % Show PhoneNumber only if present
401- PhoneNumber length 0 gt {
402- PhoneNumber show
403- PhoneNumber stringwidth pop neg StandardFontSize neg rmoveto
404- } if
405-
406- StandardFontName findfont
407- StandardFontSize 1 add scalefont
408- setfont
409- } def
410-
411- /DrawDateLine {
412- 0.6 CheckWidth mul DateLineHeight moveto
413- (Date) show
414- 1 inch 0 rlineto
415- } def
416-
417- /DrawBankInfo {
418- LeftMargin BankInfoHeight moveto
419-
420- BankName show
421- BankName stringwidth pop neg StandardFontSize neg rmoveto
422-
423- StandardFontName findfont
424- StandardFontSize 1 sub scalefont
425- setfont
426-
427- BankAddr1 show
428- BankAddr1 stringwidth pop neg StandardFontSize neg rmoveto
429-
430- % Show Addr2 only if present
431- BankAddr2 length 0 gt {
432- BankAddr2 show
433- BankAddr2 stringwidth pop neg StandardFontSize neg rmoveto
434- } if
435-
436- BankCityStateZip show
437- BankCityStateZip stringwidth pop neg StandardFontSize neg rmoveto
438-
439- StandardFontName findfont
440- StandardFontSize 1 add scalefont
441- setfont
442- } def
443-
444- /DrawPayeeLine {
445-
446- LeftMargin PayeeLineHeight moveto
447- (ORDER OF) show
448- (ORDER OF) stringwidth pop neg StandardFontSize rmoveto
449- (PAY TO THE) show
450- 0 StandardFontSize neg rmoveto
451- 4 0 rmoveto
452- currentpoint mark
453-
454- CheckWidth PayeeLineHeight moveto
455- RightMargin neg 0 rmoveto
456- AmountBoxWidth neg 0 rmoveto
457-
458- 0 AmountBoxHeight rlineto
459- AmountBoxWidth 0 rlineto
460- 0 AmountBoxHeight neg rlineto
461- AmountBoxWidth neg 0 rlineto
462-
463- -4 0 rmoveto
464-
465- /Helvetica-Bold findfont
466- 14 scalefont
467- setfont
468-
469- ($) stringwidth pop neg 0 rmoveto
470- ($) show
471- ($) stringwidth pop neg 0 rmoveto
472-
473- -4 0 rmoveto
474- cleartomark
475- lineto
476-
477- StandardFontName findfont
478- StandardFontSize scalefont
479- setfont
480-
481- } def
482-
483- /DrawMICR {
484- % 0.25 high, 5.6875 from right edge should be in the middle
485- % of the tolerance band
486- CheckWidth 0.25 inch moveto
487- -5.6875 inch 0 inch rmoveto
488- MICRHorTweak MICRVerTweak rmoveto
489-
490- save
491- MICRFontName findfont
492- MICRFontSize scalefont
493- setfont
494- TransitSymbol show
495- RoutingNumber show
496- TransitSymbol show
497- ( ) show
498- % Pad with spaces if acct number is short
499- 12 AccountNumber length sub {( ) show} repeat
500- AccountNumber show
501- OnUsSymbol show
502- ( ) show
503- % Same deal, pad w/ 0s if short check number
504- CheckNumDigits 1 sub -1 1
505- {CheckNumberString exch get 0 eq {(0) show} if } for
506- CheckNumberString show
507- restore
508- } def
509-
510- /DrawCheckNumber {
511- CheckWidth CheckHeight moveto
512- RightMargin neg TopMargin neg rmoveto
513- CheckNumFont findfont
514- CheckNumSize scalefont
515- setfont
516-
517- CheckNumberString stringwidth pop neg 0 rmoveto
518- 0 -14 rmoveto
519- CheckNumberString show
520-
521- StandardFontName findfont
522- StandardFontSize scalefont
523- setfont
524- } def
525-
526- /DrawFraction {
527- 0.6 CheckWidth mul CheckHeight moveto
528- 0 TopMargin neg rmoveto
529- 0 StandardFontSize neg rmoveto
530- Fraction show
531- } def
532-
533- /DrawStub {
534- CheckHorOffset 2 inch ge {
535- save
536- newpath
537- CheckHorOffset neg 0 translate
538- StandardFontName findfont
539- StandardFontSize 1 sub scalefont
540- setfont
541- /StubSpacing {CheckHeight 6 div} def
542- CheckHorOffset 2 div StubSpacing 5 mul moveto
543- CheckNumberString show
544- 0.3 inch StubSpacing 4 mul moveto
545- (Date ) show
546- CheckHorOffset 0.3 inch sub StubSpacing 4 mul lineto
547- 0.3 inch StubSpacing 3 mul moveto
548- (Payee ) show
549- CheckHorOffset 0.3 inch sub StubSpacing 3 mul lineto
550- 0.3 inch StubSpacing 2 mul moveto
551- (Amount ) show
552- CheckHorOffset 0.3 inch sub StubSpacing 2 mul lineto
553- 0.3 inch StubSpacing 1 mul moveto
554- (Memo ) show
555- CheckHorOffset 0.3 inch sub StubSpacing 1 mul lineto
556- stroke
557- restore
558- } if
559- } def
560-
561- /DrawVOID {
562- save
563- StandardFontName findfont
564- 50 scalefont
565- setfont
566- newpath
567- CheckWidth 2 div 1 inch moveto
568- 30 rotate
569- (V O I D) stringwidth pop 0 moveto
570- (V O I D) true charpath
571- stroke
572- restore
573- } def
574-
575- /DrawCheck {
576- % Temporarily draw boxes around the checks
577- 0 0 moveto
578- CheckWidth 0 lineto
579- CheckWidth CheckHeight lineto
580- 0 CheckHeight lineto
581- 0 0 lineto
582-
583- % Convert CheckNumber integer to a string
584- PrintCheckBody {
585- CheckNumber CheckNumberString cvs
586- DrawBankInfo
587- DrawAccountHolderInfo
588- DrawMemoLine
589- DrawSignatureLine
590- DrawAmountLine
591- DrawPayeeLine
592- DrawCheckNumber
593- DrawFraction
594- DrawDateLine
595- } if
596-
597- PrintMICRLine {
598- DrawMICR
599- } if
600-
601- PrintVOID {
602- DrawVOID
603- } if
604-
605- } def
606-
607-
608- /CurrentPage 1 def
609-
610- NumPages -1 1 {
611- /CheckNumber CheckNumber ChecksPerPage add def
612- CheckHorOffset CheckVerOffset translate
613-
614- StandardFontName findfont
615- StandardFontSize scalefont
616- setfont
617-
618- LineWidth setlinewidth
619-
620- % Loop through printing checks, starting with the bottom one
621-
622- ChecksPerPage -1 1 {
623- /CheckNumber CheckNumber 1 sub def
624- newpath
625-
626- DrawCheck
627- DrawStub % But only if there is room
628-
629- stroke
630- 0 CheckHeight translate
631- } for
632-
633- showpage
634- /CheckNumber CheckNumber ChecksPerPage add def
635- /CurrentPage CurrentPage 1 add def
636-
637- } for
638- ';
639-
640-}
example_check.ps.newView
@@ -1,0 +1,510 @@
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 +
freecheckView
@@ -1,0 +1,717 @@
1 +#!/usr/bin/perl
2 +
3 +#---------------
4 +#
5 +# FreeCheck - a free check printing application released
6 +# under the GNU General Public Licene.
7 +#
8 +# Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
9 +#
10 +# This program is free software; you can redistribute it and/or modify
11 +# it under the terms of the GNU General Public License as published by
12 +# the Free Software Foundation; either version 2 of the License, or
13 +# (at your option) any later version.
14 +#
15 +# This program is distributed in the hope that it will be useful,
16 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
17 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 +# GNU General Public License for more details.
19 +#
20 +# You should have received a copy of the GNU General Public License
21 +# along with this program; if not, write to the Free Software
22 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 +#
24 +#---------------
25 +
26 +$version = "0.2";
27 +$ConfigFile = "freecheck.cfg";
28 +
29 +use Getopt::Long;
30 +
31 +# This tells us how to format the strings from the cfg file
32 +# so we can print it as a PostScript definition
33 +# The key read will replace "value" for each of these
34 +# Strings are enclosed in parentheses (String) (Foobar)
35 +# Fonts are preceded by a "/" /FontName /Arial
36 +# Digits are fine as they are Digit 123
37 +# Booleans are fine too Bool true
38 +# But to be safe, do digits and bools as subroutines:
39 +# Subroutines are in {} {subr} {3 mul}
40 +
41 +%Formats = qw(
42 + # Globals
43 + MICRFontName /value
44 + MICRFontSize {value}
45 + TransitSymbol (value)
46 + OnUsSymbol (value)
47 + AmountSymbol (value)
48 + DashSymbol (value)
49 + MICRVerTweak {value}
50 + MICRHorTweak {value}
51 + # Account
52 + CheckNumber {value}
53 + PrintCheckBody {value}
54 + PrintMICRLine {value}
55 + NumPages {value}
56 + Name1 (value)
57 + Name2 (value)
58 + Address1 (value)
59 + Address2 (value)
60 + CityStateZip (value)
61 + PhoneNumber (value)
62 + BankName (value)
63 + BankAddr1 (value)
64 + BankAddr2 (value)
65 + BankCityStateZip (value)
66 + RoutingNumber (value)
67 + AccountNumber (value)
68 + Fraction (value)
69 + PrintVOID {value}
70 + # Styles
71 + StandardFontName /value
72 + StandardFontSize {value}
73 + CheckNumDigits {value}
74 + CheckNumFont /value
75 + CheckNumSize {value}
76 + MemoLineHeight {value}
77 + SignatureLineHeight {value}
78 + BankInfoHeight {value}
79 + AmountLineHeight {value}
80 + PayeeLineHeight {value}
81 + DateLineHeight {value}
82 + # Check Blank Types
83 + CheckHeight {value}
84 + CheckWidth {value}
85 + CheckHorOffset {value}
86 + CheckVerOffset {value}
87 + ChecksPerPage {value}
88 + LeftMargin {value}
89 + RightMargin {value}
90 + TopMargin {value}
91 + );
92 +
93 +# Parse command line options and deal with them:
94 +
95 +GetOptions ("account:s", # Account definition file
96 + "checknum:i", # Check number optional (overrides acct file)
97 + "pages:i", # Number of pages to print
98 + "checkstyle:s", # Check style (defaults to "normal_style.ps"
99 + "checktype:s", # Check blank definition
100 + "nomicr", # Prevents MICR line from printing (body only)
101 + "nobody", # Prevents body from printing (MICR line only)
102 + "showaccounts", # Show available accounts
103 + "showstyles", # Show available check styles
104 + "showblanks", # Show available check blanks
105 + "test", # Don't increment check n, and print VOID
106 + "cgi:s", # Accept big string from CGI script (or similar)
107 + "help")
108 +
109 +or Show_Usage();
110 +
111 +if ($opt_help) {
112 + Show_Usage();
113 +}
114 +
115 +# Some defaults...
116 +if (!$opt_cgi) {
117 + $opt_account = "sample";
118 + $opt_checktype = "MVG3001";
119 + $opt_checkstyle = "normal";
120 +}
121 +
122 +# Pull the config file into a string...
123 +$config_file = read_file($ConfigFile);
124 +
125 +# See what sections are available
126 +Get_Sections();
127 +
128 +# If we're missing the [Global] section, or if a requested section
129 +# cannot be found, die.
130 +if (!$global_found) {
131 + die ("No [Global] section found in config file\n");
132 +}
133 +
134 +if ($accounts !~ /${opt_account}/i) {
135 + die ("Account $opt_account not found in config file\n");
136 +}
137 +
138 +if ($checkblanks !~ /$opt_checktype/i) {
139 + die ("Check type $opt_checktype not found in config file\n");
140 +}
141 +
142 +if ($checkstyles !~ /$opt_checkstyle/i) {
143 + die ("Style $opt_checkstyle not found in config file\n");
144 +}
145 +
146 +# Show list of available sections, if requested
147 +if ($opt_showaccounts || $opt_showstyles || $opt_showblanks) {
148 + print "\nFreeCheck v$version\n";
149 + if ($opt_showaccounts) {
150 + print "Accounts:\n";
151 + foreach (split(/\s+/,$accounts)) {
152 + print "\t$_\n";
153 + }
154 + }
155 + if ($opt_showstyles) {
156 + print "Check Styles:\n";
157 + foreach (split(/\s+/,$checkstyles)) {
158 + print "\t$_\n";
159 + }
160 + }
161 + if ($opt_showblanks) {
162 + print "Check Types:\n";
163 + foreach (split(/\s+/,$checkblanks)) {
164 + print "\t$_\n";
165 + }
166 + }
167 + die("\n");
168 +}
169 +
170 +# Go through the config and fill up a hash with PostScript defines...
171 +Parse_Config($config_file);
172 +
173 +# Overwrite anything we got from the config file with what was on the
174 +# Command Line (if anything...)
175 +
176 +if ($opt_checknum) {
177 + $Definitions{"CheckNumber"} = $opt_checknum;
178 +}
179 +
180 +if ($opt_pages) {
181 + $Definitions{"NumPages"} = $opt_pages;
182 +}
183 +
184 +if ($opt_nomicr) {
185 + $Definitions{"PrintMICRLine"} = "false";
186 +}
187 +
188 +if ($opt_nobody) {
189 + $Definitions{"PrintCheckBody"} = "false";
190 +}
191 +
192 +# This probably isn't in the config file (although it might be...)
193 +# so cover both possibilites (true/false)
194 +if ($opt_test) {
195 + $Definitions{"PrintVOID"} = "true";
196 +} else {
197 + $Definitions{"PrintVOID"} = "false";
198 +}
199 +
200 +# the --cgi option lets us pass in name value pairs in a string.
201 +# This will overwrite anything we got from the config file, or
202 +# from the other command line options (--cgi has the last word)
203 +# Parse as follows:
204 +# name is the first word, everything following it is the value
205 +# each line contains one name/value pair.
206 +
207 +while ( $opt_cgi =~ /(^\w+)\s+?(.*$)/mcg ) {
208 + $Definitions{$1} = $2;
209 +}
210 +
211 +# If there's a dash in the account string, replace it with the dash symbol
212 +$Definitions{"AccountNumber"} =~ s/\-/$Definitions{"DashSymbol"}/g;
213 +
214 +# Print PostScript
215 +
216 +# Initial stuff:
217 +
218 +print "%!\n";
219 +print "/inch {72 mul} def\n";
220 +
221 +# Go through $Definitions and print them out PostScript-Like
222 +Print_Defs();
223 +
224 +# Then print the main body
225 +Print_Body();
226 +
227 +# Update the config file with the new check number, if it's not just a test
228 +if (!$opt_test) {
229 + $next_check_number = $Definitions{"CheckNumber"}
230 + + ($Definitions{"NumPages"} * $Definitions{"ChecksPerPage"});
231 +
232 + $config_file = Replace_Val($config_file, "Account", $opt_account,
233 + "CheckNumber", $next_check_number);
234 + write_file ("freecheck.cfg", $config_file);
235 +}
236 +
237 +###############
238 +# Subroutines #
239 +###############
240 +
241 +# read_file and write_file shamelessly stolen from the File::Slurp module
242 +# Short enough, and I didn't want to require a non-standard module
243 +
244 +sub read_file
245 +{
246 + my ($file) = @_;
247 +
248 + local(*F);
249 + my $r;
250 + my (@r);
251 +
252 + open(F, "<$file") || die "open $file: $!";
253 + @r = <F>;
254 + close(F);
255 +
256 + return @r if wantarray;
257 + return join("",@r);
258 +}
259 +
260 +sub write_file
261 +{
262 + my ($f, @data) = @_;
263 +
264 + local(*F);
265 +
266 + open(F, ">$f") || die "open >$f: $!";
267 + (print F @data) || die "write $f: $!";
268 + close(F) || die "close $f: $!";
269 + return 1;
270 +}
271 +
272 +# Wow, this is ugly! Anybody have a better suggestion?
273 +sub Parse_Config {
274 + local ($config_file) = ($_[0]);
275 + # Find each section we're looking for...
276 + while ($config_file =~ /^\[\s*(
277 + Global |
278 + Account\s+${opt_account} |
279 + Style\s+${opt_checkstyle} |
280 + CheckBlank\s+${opt_checktype}
281 + )\s*\]/xmgci) {
282 + # and get the lines under it one by one
283 + while ($config_file =~ /(^.+$)/mgc) {
284 + $line = $+;
285 + # If this line is a comment, skip it
286 + if ($line =~ /^#/) {
287 + next;
288 + }
289 + # If the line we just found is a new section..."[...]"
290 + if ($line =~ /^\[.+\]/) {
291 + # and it is another section we're looking for
292 + # Grab the next line, and keep going
293 + if ($line =~ /\[\s*(
294 + Global |
295 + Account\s+${opt_account} |
296 + Style\s+${opt_checkstyle} |
297 + CheckBlank\s+${opt_checktype}
298 + )\s*]/xi) {
299 + # Grab the next line, and keep going
300 + next;
301 + } else {
302 + # Not a section we need, so break out
303 + # of the loop
304 + last;
305 + }
306 + }
307 +
308 + ($key, $val) = split (/\s*=\s*/,$line);
309 + # Need to strip trailing whitespace...
310 + $val =~ s/\s*$//;
311 + $Definitions{$key} = $val;
312 + } # line-by-line while
313 + } # section match conditional
314 +}
315 +
316 +sub Replace_Val {
317 + local ($string, $section, $name, $key, $value) =
318 + ($_[0], $_[1], $_[2], $_[3], $_[4]);
319 + # We want to get "[section name] ... key = value" and replace it
320 + # with the new value.
321 +
322 + # s - "." matches ANYTHING including newline
323 + # m - ^ and $ match after and before any newline
324 + # in this case, ".+?" means the minimum number of <anything> i.e. end
325 + # when we find the first instance of $key after [section name]
326 + $string =~
327 + s/(^\[\s*$section\s+$name\s*\].+?^${key}\s*=\s*).*?$/$+$value/smi;
328 + $string;
329 +}
330 +# Given a section type, list all the section names of that type
331 +sub Get_Sections {
332 + local $section;
333 + while ($config_file =~ /^\[\s*(
334 + Global |
335 + Account.+ |
336 + Style.+ |
337 + CheckBlank.+
338 + )\s*\]/xmgci) {
339 + $section = $+;
340 + if ( $section =~/CheckBlank\s+(.+)/i ) {
341 + $checkblanks = "$+ $checkblanks";
342 + } elsif ( $section =~/Style\s+(.+)/i ) {
343 + $checkstyles = "$+ $styles";
344 + } elsif ( $section =~/Account\s+(.+)/i ) {
345 + $accounts = "$+ $accounts";
346 + } elsif ( $section =~/Global/i ) {
347 + $global_found = "true";
348 + }
349 + }
350 +}
351 +
352 +sub Show_Usage {
353 + print "\nFreeCheck v.$version - a Free Check printing Utility\n\n";
354 + print "Usage: freecheck <options>:\n";
355 + print "\n";
356 + print "options:\n";
357 + print " --account <filename> account to use (default \"$opt_account\")\n";
358 + print " --checknum <integer> starting check number (overrides cfg)\n";
359 + print " --pages <integer> number of pages to print (overrides cfg)\n";
360 + print " --checkstyle <filename> check style to use (default \"$opt_checkstyle\")\n";
361 + print " --checktype <filename> blank check type to use (default \"$opt_checktype\")\n";
362 + print " --nomicr do not print MICR line\n";
363 + print " --nobody do not print check body\n";
364 + print " --showaccounts show all configured accounts\n";
365 + print " --showstyles show all configured check styles\n";
366 + print " --showblanks show all configured check blanks\n";
367 + print " --help print this message\n";
368 + print " --test print but don't increment check number\n";
369 + print " and print VOID on the check\n";
370 + print " --cgi accept string from CGI script (see docs)\n";
371 + print "\nconfig file \"freecheck.cfg\" must be in the same directory,\n";
372 + print "as the freecheck executable (this will change in the future...)\n";
373 + die "\n";
374 +}
375 +
376 +sub Print_Defs {
377 + # Go through each def in the hash table, and print according to the
378 + # formatting hash
379 + while ( ($key, $val) = each (%Definitions) ) {
380 + print "/$key\t";
381 + $_ = $Formats{$key};
382 + s/value/$val/;
383 + print;
384 + print " def\n";
385 + }
386 +}
387 +
388 +sub Print_Body {
389 +
390 +# This is the main body of the postscript file, that acts on all of the
391 +# definitions we got from the config file.
392 +
393 +print <<END_OF_POSTSCRIPT
394 +% Other Constants:
395 +
396 +% Size of the rectangular box for the amount (digits)
397 +/AmountBoxWidth {1 inch} def
398 +/AmountBoxHeight {0.25 inch} def
399 +
400 +/LineWidth {0.3} def
401 +
402 +% Convert CheckNumber integer to a string of appropriate length
403 +/CheckNumberString CheckNumber log floor 1 add cvi string def
404 +
405 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406 +% Helpful Printing Routines %
407 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 +
409 +% Shows a line, then does a "carriage return / line feed"
410 +% But only if the string exists (more than 0 chars)
411 +% (How do we get the current font size (height)?)
412 +
413 +/ShowAndCR {
414 + % A couple copies of the string (now 3 on stack)
415 + dup dup
416 + length 0 gt { % First copy
417 + show % Second copy
418 + stringwidth pop neg 0 rmoveto % Third copy & move back
419 + neg 0 exch rmoveto % line down
420 + } if
421 +} def
422 +
423 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424 +% Feature Printing Routines %
425 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 +
427 +/DrawMemoLine {
428 + LeftMargin MemoLineHeight CheckHeight mul moveto
429 + 2.5 inch 0 inch rlineto
430 + -2.5 inch 0 inch rmoveto
431 + 0 2 rmoveto
432 + (for) show
433 +} def
434 +
435 +/DrawSignatureLine { % Expects height of signature line
436 + % and right edge of check for
437 + % beginning position
438 +
439 + CheckWidth SignatureLineHeight CheckHeight mul moveto
440 + RightMargin neg 0 rmoveto
441 + -2.5 inch 0 rmoveto
442 + 2.5 inch 0 inch rlineto
443 +
444 +} def
445 +
446 +/DrawAmountLine {
447 + CheckWidth AmountLineHeight CheckHeight mul moveto
448 + RightMargin neg 0 rmoveto
449 + (DOLLARS) stringwidth pop neg 0 rmoveto
450 + (DOLLARS) show
451 + (DOLLARS) stringwidth pop neg 0 rmoveto
452 + -2 0 rmoveto
453 + LeftMargin AmountLineHeight CheckHeight mul lineto
454 +} def
455 +
456 +/DrawAccountHolderInfo {
457 + LeftMargin CheckHeight moveto
458 + 0 TopMargin neg rmoveto
459 + 0 StandardFontSize neg rmoveto
460 +
461 + StandardFontSize Name1 ShowAndCR
462 + StandardFontSize Name2 ShowAndCR
463 +
464 + StandardFontName findfont
465 + StandardFontSize 1 sub scalefont
466 + setfont
467 +
468 + StandardFontSize 1 sub Address1 ShowAndCR
469 + StandardFontSize 1 sub Address2 ShowAndCR
470 + StandardFontSize 1 sub CityStateZip ShowAndCR
471 + StandardFontSize 1 sub PhoneNumber ShowAndCR
472 +
473 + StandardFontName findfont
474 + StandardFontSize 1 add scalefont
475 + setfont
476 +} def
477 +
478 +/DrawDateLine {
479 + 0.6 CheckWidth mul DateLineHeight CheckHeight mul moveto
480 + (Date) show
481 + 1 inch 0 rlineto
482 +} def
483 +
484 +/DrawBankInfo {
485 + LeftMargin BankInfoHeight CheckHeight mul moveto
486 +
487 + StandardFontSize BankName ShowAndCR
488 +
489 + StandardFontName findfont
490 + StandardFontSize 1 sub scalefont
491 + setfont
492 +
493 + StandardFontSize 1 sub BankAddr1 ShowAndCR
494 + StandardFontSize 1 sub BankAddr2 ShowAndCR
495 + StandardFontSize 1 sub BankCityStateZip ShowAndCR
496 +
497 + StandardFontName findfont
498 + StandardFontSize 1 add scalefont
499 + setfont
500 +} def
501 +
502 +/DrawPayeeLine {
503 +
504 + LeftMargin PayeeLineHeight CheckHeight mul moveto
505 + (ORDER OF) show
506 + (ORDER OF) stringwidth pop neg StandardFontSize rmoveto
507 + (PAY TO THE) show
508 + 0 StandardFontSize neg rmoveto
509 + 4 0 rmoveto
510 + currentpoint mark
511 +
512 + CheckWidth PayeeLineHeight CheckHeight mul moveto
513 + RightMargin neg 0 rmoveto
514 + AmountBoxWidth neg 0 rmoveto
515 +
516 + 0 AmountBoxHeight rlineto
517 + AmountBoxWidth 0 rlineto
518 + 0 AmountBoxHeight neg rlineto
519 + AmountBoxWidth neg 0 rlineto
520 +
521 + -4 0 rmoveto
522 +
523 + /Helvetica-Bold findfont
524 + 14 scalefont
525 + setfont
526 +
527 + (\$) stringwidth pop neg 0 rmoveto
528 + (\$) show
529 + (\$) stringwidth pop neg 0 rmoveto
530 +
531 + -4 0 rmoveto
532 + cleartomark
533 + lineto
534 +
535 + StandardFontName findfont
536 + StandardFontSize scalefont
537 + setfont
538 +
539 +} def
540 +
541 +/DrawMICR {
542 + % 0.25 high, 5.6875 from right edge should be in the middle
543 + % of the tolerance band
544 + CheckWidth 0.25 inch moveto
545 + -5.6875 inch 0 inch rmoveto
546 + MICRHorTweak MICRVerTweak rmoveto
547 +
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
584 +} def
585 +
586 +/DrawCheckNumber {
587 + CheckWidth CheckHeight moveto
588 + RightMargin neg TopMargin neg rmoveto
589 + CheckNumFont findfont
590 + CheckNumSize scalefont
591 + setfont
592 +
593 + CheckNumberString stringwidth pop neg 0 rmoveto
594 + 0 -14 rmoveto
595 + CheckNumberString show
596 +
597 + StandardFontName findfont
598 + StandardFontSize scalefont
599 + setfont
600 +} def
601 +
602 +/DrawFraction {
603 + 0.6 CheckWidth mul CheckHeight moveto
604 + 0 TopMargin neg rmoveto
605 + 0 StandardFontSize neg rmoveto
606 + Fraction show
607 +} def
608 +
609 +/DrawStub {
610 + CheckHorOffset 2 inch ge {
611 + save
612 + newpath
613 + CheckHorOffset neg 0 translate
614 + StandardFontName findfont
615 + StandardFontSize 1 sub scalefont
616 + setfont
617 + /StubSpacing {CheckHeight 6 div} def
618 + CheckHorOffset 2 div StubSpacing 5 mul moveto
619 + CheckNumberString show
620 + 0.3 inch StubSpacing 4 mul moveto
621 + (Date ) show
622 + CheckHorOffset 0.3 inch sub StubSpacing 4 mul lineto
623 + 0.3 inch StubSpacing 3 mul moveto
624 + (Payee ) show
625 + CheckHorOffset 0.3 inch sub StubSpacing 3 mul lineto
626 + 0.3 inch StubSpacing 2 mul moveto
627 + (Amount ) show
628 + CheckHorOffset 0.3 inch sub StubSpacing 2 mul lineto
629 + 0.3 inch StubSpacing 1 mul moveto
630 + (Memo ) show
631 + CheckHorOffset 0.3 inch sub StubSpacing 1 mul lineto
632 + stroke
633 + restore
634 + } if
635 +} def
636 +
637 +/DrawVOID {
638 + save
639 + StandardFontName findfont
640 + 50 scalefont
641 + setfont
642 + newpath
643 + CheckWidth 2 div 1 inch moveto
644 + 30 rotate
645 + (V O I D) stringwidth pop 0 moveto
646 + (V O I D) true charpath
647 + stroke
648 + restore
649 +} def
650 +
651 +/DrawCheck {
652 +
653 + % Convert CheckNumber integer to a string
654 + CheckNumber CheckNumberString cvs
655 + PrintCheckBody {
656 + DrawBankInfo
657 + DrawAccountHolderInfo
658 + DrawMemoLine
659 + DrawSignatureLine
660 + DrawAmountLine
661 + DrawPayeeLine
662 + DrawCheckNumber
663 + DrawFraction
664 + DrawDateLine
665 + DrawStub
666 + } if
667 +
668 + PrintMICRLine {
669 + DrawMICR
670 + } if
671 +
672 + PrintVOID {
673 + % Draw border around check, and print "VOID" for testing
674 + 0 0 moveto
675 + CheckWidth 0 lineto
676 + CheckWidth CheckHeight lineto
677 + 0 CheckHeight lineto
678 + 0 0 lineto
679 +
680 + DrawVOID
681 + } if
682 +
683 +} def
684 +
685 +
686 +/CurrentPage 1 def
687 +
688 +NumPages -1 1 {
689 + /CheckNumber CheckNumber ChecksPerPage add def
690 + CheckHorOffset CheckVerOffset translate
691 +
692 + StandardFontName findfont
693 + StandardFontSize scalefont
694 + setfont
695 +
696 + LineWidth setlinewidth
697 +
698 + % Loop through printing checks, starting with the bottom one
699 +
700 + ChecksPerPage -1 1 {
701 + /CheckNumber CheckNumber 1 sub def
702 + newpath
703 + DrawCheck
704 + stroke
705 + 0 CheckHeight translate
706 + } for
707 +
708 + showpage
709 + /CheckNumber CheckNumber ChecksPerPage add def
710 + /CurrentPage CurrentPage 1 add def
711 +
712 +} for
713 +
714 +END_OF_POSTSCRIPT
715 +;
716 +
717 +}
freecheck.cgiView
@@ -1,0 +1,351 @@
1 +#!/usr/bin/perl
2 +
3 +#---------------
4 +#
5 +# FreeCheck - a free check printing application released
6 +# under the GNU General Public Licene.
7 +#
8 +# Copyright (C) 2000 Eric Sandeen (eric_sandeen@bigfoot.com)
9 +#
10 +# This program is free software; you can redistribute it and/or modify
11 +# it under the terms of the GNU General Public License as published by
12 +# the Free Software Foundation; either version 2 of the License, or
13 +# (at your option) any later version.
14 +#
15 +# This program is distributed in the hope that it will be useful,
16 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
17 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 +# GNU General Public License for more details.
19 +#
20 +# You should have received a copy of the GNU General Public License
21 +# along with this program; if not, write to the Free Software
22 +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 +#
24 +#---------------
25 +
26 +###########################################
27 +# WARNING WARNING WARNING WARNING WARNING #
28 +###########################################
29 +# THIS CODE EXECUTES AT LEAST ONE EXTERNAL PROGRAM, BASED ON
30 +# STRINGS PASSED IN FROM THE FORM. A FEEBLE EFFORT HAS BEEN
31 +# MADE TO SANITIZE THOSE STRINGS, BUT THERE COULD STILL BE
32 +# A SECURITY RISK HERE. YOU HAVE BEEN WARNED
33 +##########################################
34 +
35 +# This script will generate a form that allows users to fill out information to
36 +# be printed on checks, and they get back either a PostScript or a PDF document.
37 +# Currently, the freecheck script and config files need to be in the same dir as
38 +# the CGI. If you want to generate PDFs, you need GhostScript. You also really
39 +# need the 6.x series, or the PDFs will look horrible, and checks printed almost
40 +# certainly will not be machine readable.
41 +
42 +# The freecheck executable script, and the freecheck config file
43 +# (freecheck.cfg) should be in the same dir as this script.
44 +
45 +use CGI qw(:standard);
46 +
47 +# The path to the GhostScript executable, with escaped "/"s
48 +$GS = "\/usr\/bin\/gs";
49 +
50 +# Get the cookie to set the defaults, if it's there...
51 +%pairs_hash = cookie('FreeCheck');
52 +
53 +# If it's not there, set minimum defaults so the main script won't bonk
54 +if (!%pairs_hash) {
55 + %pairs_hash = ( "NumPages", "1",
56 + "PrintCheckBody", "true",
57 + "PrintMICRLine", "true",
58 + "CheckNumber", "100");
59 +}
60 +
61 +# If we have no parameters passed, generate the initial page with default vals
62 +if (!param()) {
63 + print header;
64 + print start_html('FreeCheck Online'),
65 + #"Cookie:",br,
66 + #%pairs_hash,
67 + h1('FreeCheck'),
68 + "A free check printing utility",
69 + br,
70 + "Copyright (C) 2000 Eric Sandeen (eric_sandeen @ bigfoot.com)",
71 + hr,
72 +
73 + start_form,
74 + submit( -name=>"Submit",
75 + -label=>" Get my checks! "),
76 + h2('Check Information'),
77 + h3('Account Holder Information'),
78 +
79 + textfield( -name=>'Name1',
80 + -default=>$pairs_hash{"Name1"}),
81 + " Name 1", br,
82 +
83 + textfield( -name=>'Name2',
84 + -default=>$pairs_hash{"Name2"}),
85 + " Name 2", br,
86 +
87 + textfield( -name=>'Address1',
88 + -default=>$pairs_hash{"Address1"}),
89 + " Address Line 1", br,
90 +
91 + textfield( -name=>'Address2',
92 + -default=>$pairs_hash{"Address2"}),
93 + " Address Line 2", br,
94 +
95 + textfield( -name=>'CityStateZip',
96 + -default=>$pairs_hash{"CityStateZip"}),
97 + " City, State, Zip", br,
98 +
99 + textfield( -name=>'PhoneNumber',
100 + -default=>$pairs_hash{"PhoneNumber"}),
101 + " Phone Number", br,
102 +
103 + h3('Account Information'),
104 + textfield( -name=>'RoutingNumber',
105 + -default=>$pairs_hash{"RoutingNumber"},
106 + -size=>9, -maxlength=>9),
107 + " Routing Number", br,
108 +
109 + textfield( -name=>'AccountNumber',
110 + -default=>$pairs_hash{"AccountNumber"}),
111 + " Account Number", br,
112 +
113 + textfield( -name=>'Fraction',
114 + -default=>$pairs_hash{"Fraction"}),
115 + " Fraction (top of check)", br,
116 +
117 + h3('Bank Information'),
118 + textfield( -name=>'BankName',
119 + -default=>$pairs_hash{"BankName"}),
120 + " Bank Name", br,
121 +
122 + textfield( -name=>'BankAddr1',
123 + -default=>$pairs_hash{"BankAddr1"}),
124 + " Bank Address1", br,
125 +
126 + textfield( -name=>'BankAddr2',
127 + -default=>$pairs_hash{"BankAddr2"}),
128 + " Bank Address 2", br,
129 +
130 + textfield( -name=>'BankCityStateZip',
131 + -default=>$pairs_hash{"BankCityStateZip"}),
132 + " Bank City, State, Zip", br,
133 +
134 + h2('Printing Options'),
135 + textfield( -name=>'CheckNumber',
136 + -default=>$pairs_hash{"CheckNumber"},
137 + -size=>7,
138 + -maxlength=>7),
139 + " Starting Check Number",
140 + br,
141 +
142 + "Select check style: ",
143 + popup_menu( -name=>'CheckStyle',
144 + -values=>['Normal'],
145 + -default=>$pairs_hash{"CheckStyle"}),
146 + br,
147 +
148 + "Select check blank: ",
149 + popup_menu( -name=>'CheckType',
150 + -values=>['MVG3001','MVG1000','MVD1001'],
151 + -default=>$pairs_hash{"CheckType"},
152 + -labels=>{ 'MVG3001'=>'VersaCheck MVG3001',
153 + 'MVG1000'=>'VersaCheck MVG1000',
154 + 'MVD1001'=>'VersaCheck MVD1001'}),
155 + p,
156 +
157 +
158 + checkbox( -name=>'PrintCheckBody',
159 + -checked=>$pairs_hash{"PrintCheckBody"},
160 + -value=>'true',
161 + -label=>' Print Check Body'),
162 + br,
163 +
164 + checkbox( -name=>'PrintMICRLine',
165 + -checked=>$pairs_hash{"PrintMICRLine"},
166 + -value=>'true',
167 + -label=>' Print MICR Line'),
168 + br,
169 +
170 + checkbox( -name=>'Test',
171 + -checked=>$pairs_hash{"Test"},
172 + -value=>'true',
173 + -label=>' Print voided test checks'),
174 + p,
175 +
176 + "Select Output Format:",
177 + br,
178 + em("Be sure to de-select \"Fit to Page\" when printing PDFs"),
179 + br,
180 + radio_group( -name=>'OutputType',
181 + -values=>['PDF', 'PostScript'],
182 + -labels=>{'PDF'=>' PDF',
183 + 'PostScript'=>' PostScript'},
184 + -default=>$pairs_hash{"OutputType"},
185 + -linebreak=>'true'),
186 + br,
187 +
188 + "Number of Pages to Print: ",
189 + textfield( -name=>'NumPages',
190 + -default=>$pairs_hash{"NumPages"},
191 + -size=>2,
192 + -maxlength=>80),
193 + p,
194 +
195 + "Save information in a cookie?",
196 + br,
197 + em("Note: if you're security-paranoid, and you've entered real data,
198 + this might not be a such a good idea at this point..."),
199 + br,
200 + radio_group( -name=>'Cookie',
201 + -values=>['ClearCookie', 'SetCookie'],
202 + -default=>$pairs_hash{"Cookie"},
203 + -labels=>{'ClearCookie'=>' Don\'t set, or clear',
204 + 'SetCookie'=>' Set a cookie'},
205 + -linebreak=>'true'),
206 + br,
207 + submit( -name=>"Submit",
208 + -label=>" Get my checks! "),
209 + end_form,
210 + em("If Netscape wants to save \"freecheck.cgi\" just rename it to
211 + \"mychecks.[pdf,ps]\" - I don't know why this happens"),
212 + hr;
213 + print end_html;
214 +}
215 +
216 +# If Submit button has been pressed , then process the values
217 +if (param("Submit")) {
218 +
219 + # Get a hash of all the fields and their values
220 + my @names = param();
221 + $pairs_string = "";
222 + foreach (@names) {
223 + $name = $_;
224 + $value = param($_);
225 + #$pairs_string = $pairs_string . $_ . " $value\n";
226 + $pairs_hash{$name} = $value;
227 + }
228 + # "Submit" is the only thing we don't want to store
229 + delete $pairs_hash{"Submit"};
230 +
231 + # Deal with the form elements that didn't go in the hash:
232 + $CheckStyle = param("CheckStyle");
233 + $CheckType = param("CheckType");
234 +
235 + # For checkboxes, delete them from the hash/cookie if not checked
236 + if ( param("PrintMICRLine") ne "true" ) {
237 + $MICR = "--nomicr";
238 + delete $pairs_hash{"PrintMICRLine"};
239 + }
240 +
241 + if ( param("PrintCheckBody") ne "true" ) {
242 + $BODY = "--nobody";
243 + delete $pairs_hash{"PrintCheckBody"};
244 + }
245 +
246 + if ( param("Test") eq "true") {
247 + $TEST = "--test";
248 + } else {
249 + delete $pairs_hash{"Test"};
250 + }
251 +
252 + # Turn the hash into a string (this is a bit goofy, I guess...)
253 + # We do it as a hash initially to make it easier to fill in the
254 + # forms, above.
255 + # This is what is passed to the check generation script
256 +
257 + $pairs_string = "";
258 + $NotDefs="Submit Cookie Test OutputType CheckStyle CheckType";
259 + while ( ($name,$value) = each(%pairs_hash) ) {
260 + unless ($NotDefs =~ /${name}/ ) {
261 + $pairs_string = $pairs_string . "$name $value\n";
262 + }
263 + }
264 +
265 + # Create the argument string
266 + $arguments = "--checkstyle $CheckStyle --checktype $CheckType $MICR $BODY $TEST";
267 +
268 + # This is where we should set the next check number to be printed,
269 + # if we knew how many checks per page we had... any good way
270 + # to do this....? For now, we'll just set things up semi-manually
271 +
272 + %ChecksPerPage =
273 + ("MVG3001", "3", "MVG1000", "1", "MVD1001", "1");
274 +
275 + $NextCheckNumber = param("CheckNumber") +
276 + param("NumPages") *
277 + $ChecksPerPage{param("CheckType")};
278 +
279 + $pairs_hash{"CheckNumber"} = $NextCheckNumber;
280 +
281 + # Sanitize $pairs_string and $arguments
282 + # Let's not go spawning any new shells (this is minimal security...)
283 + # Also checks for SSI strings
284 +
285 + if ($pairs_string =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
286 + kill_input();
287 + }
288 +
289 + if ($pairs_string =~ /[;><\*`\|]/s) {
290 + kill_input();
291 + }
292 +
293 + if ($arguments =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
294 + kill_input();
295 + }
296 +
297 + if ($arguments =~ /[;><\*`\|]/s) {
298 + kill_input();
299 + }
300 +
301 + if ( param("Cookie") eq "SetCookie" ) {
302 + $cookie = cookie( -name=>'FreeCheck',
303 + -value=>\%pairs_hash,
304 + -expires=>'+6M',
305 + -path=>script_name(),
306 + -domain=>server_name());
307 + } elsif ( param("Cookie") eq "ClearCookie" ) {
308 + $cookie = cookie( -name=>'FreeCheck',
309 + -value=>'',
310 + -expires=>'+1m',
311 + -path=>script_name(),
312 + -domain=>server_name());
313 + }
314 +
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 +
327 + # Generate the actual output.
328 + # The PDF thing might become an option in the main script
329 + # soon...
330 + ###########################################
331 + # WARNING WARNING WARNING WARNING WARNING #
332 + ###########################################
333 + # THIS CODE EXECUTES AT LEAST ONE EXTERNAL PROGRAM, BASED ON
334 + # STRINGS PASSED IN FROM THE FORM. A FEEBLE EFFORT HAS BEEN
335 + # MADE TO SANITIZE THOSE STRINGS, BUT THERE COULD STILL BE
336 + # A SECURITY RISK HERE. YOU HAVE BEEN WARNED
337 +
338 + print (`.\/freecheck --cgi \"$pairs_string\" $arguments $PDFConvert`);
339 +
340 +}
341 +
342 +sub kill_input {
343 + print header;
344 + print start_html("Problem with those strings...");
345 + print "You seem to have some shell metacharacters in your ";
346 + print "entered strings. Sorry, you can't do that...";
347 + print p;
348 + print "Please get those funky things out of your form, and try again";
349 + print end_html;
350 + exit;
351 +}

Built with git-ssb-web