pwd.h needs types.h; add pathnames.h
[unix-history] / usr / src / games / snake / snake / snake.c
CommitLineData
b6f0a7e4
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
a825d20f
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
65c7d3b6
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
0f528257 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
b6f0a7e4
DF
16 */
17
18#ifndef lint
19char copyright[] =
20"@(#) Copyright (c) 1980 Regents of the University of California.\n\
21 All rights reserved.\n";
a825d20f 22#endif /* not lint */
b6f0a7e4 23
384a101e 24#ifndef lint
0f528257 25static char sccsid[] = "@(#)snake.c 5.7 (Berkeley) %G%";
a825d20f 26#endif /* not lint */
384a101e
SL
27
28/*
29 * snake - crt hack game.
30 *
31 * You move around the screen with arrow keys trying to pick up money
32 * without getting eaten by the snake. hjkl work as in vi in place of
33 * arrow keys. You can leave at the exit any time.
34 *
35 * compile as follows:
36 * cc -O snake.c move.c -o snake -lm -ltermlib
37 */
38
3f63e290 39#include <sys/param.h>
384a101e 40#include <pwd.h>
3f63e290 41#include "snake.h"
0f528257 42#include "pathnames.h"
384a101e
SL
43
44#define PENALTY 10 /* % penalty for invoking spacewarp */
45
46#define EOT '\004'
47#define LF '\n'
48#define DEL '\177'
49
50#define ME 'I'
51#define SNAKEHEAD 'S'
52#define SNAKETAIL 's'
53#define TREASURE '$'
54#define GOAL '#'
55
56#define BSIZE 80
57
58struct point you;
59struct point money;
60struct point finish;
61struct point snake[6];
62
63int loot, penalty;
64int long tl, tm=0L;
384a101e 65int moves;
384a101e
SL
66char stri[BSIZE];
67char *p;
68char ch, savec;
69char *kl, *kr, *ku, *kd;
70int fast=1;
71int repeat=1;
72long tv;
73char *tn;
74
75main(argc,argv)
76int argc;
77char **argv;
78{
3f63e290
KB
79 extern char *optarg;
80 extern int optind;
81 int ch, i, j, k;
82 time_t time();
83 long atol();
384a101e 84 int stop();
384a101e 85
3f63e290
KB
86 (void)time(&tv);
87 srandom((int)tv);
384a101e 88
3f63e290
KB
89 while ((ch = getopt(argc, argv, "l:w:")) != EOF)
90 switch((char)ch) {
91#ifdef notdef
384a101e 92 case 'd':
3f63e290 93 tv = atol(optarg);
384a101e 94 break;
3f63e290 95#endif
384a101e 96 case 'w': /* width */
3f63e290 97 ccnt = atoi(optarg);
384a101e
SL
98 break;
99 case 'l': /* length */
3f63e290 100 lcnt = atoi(optarg);
384a101e 101 break;
3f63e290 102 case '?':
384a101e 103 default:
3f63e290
KB
104 fputs("usage: snake [-d seed] [-w width] [-l length]\n", stderr);
105 exit(1);
384a101e 106 }
384a101e 107
3f63e290
KB
108 penalty = loot = 0;
109 getcap();
110
111 i = MIN(lcnt, ccnt);
384a101e 112 if (i < 4) {
3f63e290
KB
113 cook();
114 printf("snake: screen too small for a fair game.\n");
115 exit(1);
384a101e 116 }
3f63e290 117
384a101e
SL
118 /*
119 * chunk is the amount of money the user gets for each $.
120 * The formula below tries to be fair for various screen sizes.
121 * We only pay attention to the smaller of the 2 edges, since
122 * that seems to be the bottleneck.
123 * This formula is a hyperbola which includes the following points:
124 * (24, $25) (original scoring algorithm)
125 * (12, $40) (experimentally derived by the "feel")
126 * (48, $15) (a guess)
127 * This will give a 4x4 screen $99/shot. We don't allow anything
128 * smaller than 4x4 because there is a 3x3 game where you can win
129 * an infinite amount of money.
130 */
131 if (i < 12) i = 12; /* otherwise it isn't fair */
132 /*
133 * Compensate for border. This really changes the game since
134 * the screen is two squares smaller but we want the default
135 * to be $25, and the high scores on small screens were a bit
136 * much anyway.
137 */
138 i += 2;
139 chunk = (675.0 / (i+6)) + 2.5; /* min screen edge */
140
141 signal (SIGINT, stop);
142 putpad(TI); /* String to begin programs that use cm */
143 putpad(KS); /* Put terminal in keypad transmit mode */
144
3f63e290
KB
145 snrand(&finish);
146 snrand(&you);
147 snrand(&money);
148 snrand(&snake[0]);
384a101e
SL
149
150 if ((orig.sg_ospeed < B9600) ||
151 ((! CM) && (! TA))) fast=0;
152 for(i=1;i<6;i++)
153 chase (&snake[i], &snake[i-1]);
154 setup();
155 mainloop();
156}
157
158/* Main command loop */
159mainloop()
160{
161 int j, k;
162
163 for (;;) {
164 int c,lastc,match;
165
166 move(&you);
167 fflush(stdout);
168 if (((c = getchar() & 0177) <= '9') && (c >= '0')) {
169 ungetc(c,stdin);
170 j = scanf("%d",&repeat);
171 c = getchar() & 0177;
172 } else {
173 if (c != '.') repeat = 1;
174 }
175 if (c == '.') {
176 c = lastc;
177 }
178 if ((Klength > 0) &&
179 (c == *KL || c == *KR || c == *KU || c == *KD)) {
180 savec = c;
181 match = 0;
182 kl = KL;
183 kr = KR;
184 ku = KU;
185 kd = KD;
186 for (j=Klength;j>0;j--){
187 if (match != 1) {
188 match = 0;
189 if (*kl++ == c) {
190 ch = 'h';
191 match++;
192 }
193 if (*kr++ == c) {
194 ch = 'l';
195 match++;
196 }
197 if (*ku++ == c) {
198 ch = 'k';
199 match++;
200 }
201 if (*kd++ == c) {
202 ch = 'j';
203 match++;
204 }
205 if (match == 0) {
206 ungetc(c,stdin);
207 ch = savec;
208 /* Oops!
209 * This works if we figure it out on second character.
210 */
211 break;
212 }
213 }
214 savec = c;
215 if(j != 1) c = getchar() & 0177;
216 }
217 c = ch;
218 }
219 if (!fast) flushi();
220 lastc = c;
221 switch (c){
36c966f5 222 case CTRL('z'):
384a101e
SL
223 suspend();
224 continue;
225 case EOT:
226 case 'x':
227 case 0177: /* del or end of file */
228 ll();
229 length(moves);
230 logit("quit");
231 done();
36c966f5 232 case CTRL('l'):
384a101e
SL
233 setup();
234 winnings(cashvalue);
235 continue;
236 case 'p':
237 case 'd':
238 snap();
239 continue;
240 case 'w':
241 spacewarp(0);
242 continue;
243 case 'A':
244 repeat = you.col;
245 c = 'h';
246 break;
247 case 'H':
248 case 'S':
249 repeat = you.col - money.col;
250 c = 'h';
251 break;
252 case 'T':
253 repeat = you.line;
254 c = 'k';
255 break;
256 case 'K':
257 case 'E':
258 repeat = you.line - money.line;
259 c = 'k';
260 break;
261 case 'P':
262 repeat = ccnt - 1 - you.col;
263 c = 'l';
264 break;
265 case 'L':
266 case 'F':
267 repeat = money.col - you.col;
268 c = 'l';
269 break;
270 case 'B':
271 repeat = lcnt - 1 - you.line;
272 c = 'j';
273 break;
274 case 'J':
275 case 'C':
276 repeat = money.line - you.line;
277 c = 'j';
278 break;
279 }
280 for(k=1;k<=repeat;k++){
281 moves++;
282 switch(c) {
283 case 's':
284 case 'h':
285 case '\b':
286 if (you.col >0) {
287 if((fast)||(k == 1))
288 pchar(&you,' ');
289 you.col--;
290 if((fast) || (k == repeat) ||
291 (you.col == 0))
292 pchar(&you,ME);
293 }
294 break;
295 case 'f':
296 case 'l':
297 case ' ':
298 if (you.col < ccnt-1) {
299 if((fast)||(k == 1))
300 pchar(&you,' ');
301 you.col++;
302 if((fast) || (k == repeat) ||
303 (you.col == ccnt-1))
304 pchar(&you,ME);
305 }
306 break;
36c966f5 307 case CTRL('p'):
384a101e
SL
308 case 'e':
309 case 'k':
310 case 'i':
311 if (you.line > 0) {
312 if((fast)||(k == 1))
313 pchar(&you,' ');
314 you.line--;
315 if((fast) || (k == repeat) ||
316 (you.line == 0))
317 pchar(&you,ME);
318 }
319 break;
36c966f5 320 case CTRL('n'):
384a101e
SL
321 case 'c':
322 case 'j':
323 case LF:
324 case 'm':
325 if (you.line+1 < lcnt) {
326 if((fast)||(k == 1))
327 pchar(&you,' ');
328 you.line++;
329 if((fast) || (k == repeat) ||
330 (you.line == lcnt-1))
331 pchar(&you,ME);
332 }
333 break;
334 }
335
336 if (same(&you,&money))
337 {
338 char xp[20];
339 struct point z;
340 loot += 25;
341 if(k < repeat)
342 pchar(&you,' ');
343 do {
3f63e290 344 snrand(&money);
384a101e
SL
345 } while (money.col == finish.col && money.line == finish.line ||
346 money.col < 5 && money.line == 0 ||
347 money.col == you.col && money.line == you.line);
348 pchar(&money,TREASURE);
349 winnings(cashvalue);
350 continue;
351 }
352 if (same(&you,&finish))
353 {
354 win(&finish);
355 ll();
356 cook();
357 printf("You have won with $%d.\n",cashvalue);
358 fflush(stdout);
359 logit("won");
360 post(cashvalue,0);
361 length(moves);
3f63e290 362 done();
384a101e
SL
363 }
364 if (pushsnake())break;
365 }
366 fflush(stdout);
367 }
368}
369
370setup(){ /*
371 * setup the board
372 */
373 int i;
374
375 clear();
376 pchar(&you,ME);
377 pchar(&finish,GOAL);
378 pchar(&money,TREASURE);
379 for(i=1; i<6; i++) {
380 pchar(&snake[i],SNAKETAIL);
381 }
382 pchar(&snake[0], SNAKEHEAD);
383 drawbox();
384 fflush(stdout);
385}
386
387drawbox()
388{
389 register int i;
390 struct point p;
391
392 p.line = -1;
393 for (i= 0; i<ccnt; i++) {
394 p.col = i;
395 pchar(&p, '-');
396 }
397 p.col = ccnt;
398 for (i= -1; i<=lcnt; i++) {
399 p.line = i;
400 pchar(&p, '|');
401 }
402 p.col = -1;
403 for (i= -1; i<=lcnt; i++) {
404 p.line = i;
405 pchar(&p, '|');
406 }
407 p.line = lcnt;
408 for (i= 0; i<ccnt; i++) {
409 p.col = i;
410 pchar(&p, '-');
411 }
412}
413
3f63e290 414snrand(sp)
384a101e
SL
415struct point *sp;
416{
384a101e
SL
417 struct point p;
418 register int i;
419
3f63e290
KB
420 for (;;) {
421 p.col = random() % ccnt;
422 p.line = random() % lcnt;
384a101e
SL
423
424 /* make sure it's not on top of something else */
3f63e290
KB
425 if (p.line == 0 && p.col < 5)
426 continue;
427 if (same(&p, &you))
428 continue;
429 if (same(&p, &money))
430 continue;
431 if (same(&p, &finish))
432 continue;
433 for (i = 0; i < 5; i++)
434 if (same(&p, &snake[i]))
435 break;
436 if (i < 5)
437 continue;
438 break;
439 }
384a101e
SL
440 *sp = p;
441}
442
7cfc1f81
S
443post(iscore, flag)
444int iscore, flag;
384a101e 445{
7cfc1f81 446 short score = iscore;
384a101e 447 int rawscores;
7cfc1f81 448 short uid;
384a101e
SL
449 short oldbest=0;
450 short allbwho=0, allbscore=0;
451 struct passwd *p, *getpwuid();
452
453 /*
454 * Neg uid, 0, and 1 cannot have scores recorded.
455 */
0f528257 456 if ((uid=getuid()) > 1 && (rawscores=open(_PATH_RAWSCORES,2))>=0) {
384a101e
SL
457 /* Figure out what happened in the past */
458 read(rawscores, &allbscore, sizeof(short));
459 read(rawscores, &allbwho, sizeof(short));
460 lseek(rawscores, ((long)uid)*sizeof(short), 0);
461 read(rawscores, &oldbest, sizeof(short));
462 if (flag) return (score > oldbest ? 1 : 0);
463
464 /* Update this jokers best */
465 if (score > oldbest) {
466 lseek(rawscores, ((long)uid)*sizeof(short), 0);
467 write(rawscores, &score, sizeof(short));
468 printf("You bettered your previous best of $%d\n", oldbest);
469 } else
470 printf("Your best to date is $%d\n", oldbest);
471
472 /* See if we have a new champ */
473 p = getpwuid(allbwho);
474 if (p == NULL || score > allbscore) {
475 lseek(rawscores, (long)0, 0);
476 write(rawscores, &score, sizeof(short));
477 write(rawscores, &uid, sizeof(short));
478 if (p != NULL)
479 printf("You beat %s's old record of $%d!\n", p->pw_name, allbscore);
480 else
481 printf("You set a new record!\n");
482 } else
483 printf("The highest is %s with $%d\n", p->pw_name, allbscore);
484 close(rawscores);
485 } else
486 if (!flag)
487 printf("Unable to post score.\n");
488 return (1);
489}
490
491/*
492 * Flush typeahead to keep from buffering a bunch of chars and then
493 * overshooting. This loses horribly at 9600 baud, but works nicely
494 * if the terminal gets behind.
495 */
496flushi()
497{
498 stty(0, &new);
499}
500int mx [8] = {
501 0, 1, 1, 1, 0,-1,-1,-1};
502int my [8] = {
503 -1,-1, 0, 1, 1, 1, 0,-1};
504float absv[8]= {
505 1, 1.4, 1, 1.4, 1, 1.4, 1, 1.4
506};
507int oldw=0;
508chase (np, sp)
509struct point *sp, *np;
510{
511 /* this algorithm has bugs; otherwise the
512 snake would get too good */
513 struct point d;
514 int w, i, wt[8];
515 double sqrt(), v1, v2, vp, max;
516 point(&d,you.col-sp->col,you.line-sp->line);
517 v1 = sqrt( (double) (d.col*d.col + d.line*d.line) );
518 w=0;
519 max=0;
520 for(i=0; i<8; i++)
521 {
522 vp = d.col*mx[i] + d.line*my[i];
523 v2 = absv[i];
524 if (v1>0)
525 vp = ((double)vp)/(v1*v2);
526 else vp=1.0;
527 if (vp>max)
528 {
529 max=vp;
530 w=i;
531 }
532 }
533 for(i=0; i<8; i++)
534 {
535 point(&d,sp->col+mx[i],sp->line+my[i]);
536 wt[i]=0;
537 if (d.col<0 || d.col>=ccnt || d.line<0 || d.line>=lcnt)
538 continue;
3f63e290
KB
539 /*
540 * Change to allow snake to eat you if you're on the money,
541 * otherwise, you can just crouch there until the snake goes
542 * away. Not positive it's right.
543 *
544 * if (d.line == 0 && d.col < 5) continue;
545 */
384a101e
SL
546 if (same(&d,&money)) continue;
547 if (same(&d,&finish)) continue;
548 wt[i]= i==w ? loot/10 : 1;
549 if (i==oldw) wt [i] += loot/20;
550 }
551 for(w=i=0; i<8; i++)
552 w+= wt[i];
553 vp = (( rand() >> 6 ) & 01777) %w;
554 for(i=0; i<8; i++)
555 if (vp <wt[i])
556 break;
557 else
558 vp -= wt[i];
559 if (i==8) {
560 printf("failure\n");
561 i=0;
562 while (wt[i]==0) i++;
563 }
564 oldw=w=i;
565 point(np,sp->col+mx[w],sp->line+my[w]);
566}
567
568spacewarp(w)
569int w;{
570 struct point p;
571 int j;
3f63e290
KB
572 char *str;
573
574 snrand(&you);
384a101e
SL
575 point(&p,COLUMNS/2 - 8,LINES/2 - 1);
576 if (p.col < 0)
577 p.col = 0;
578 if (p.line < 0)
579 p.line = 0;
580 if (w) {
3f63e290 581 str = "BONUS!!!";
384a101e
SL
582 loot = loot - penalty;
583 penalty = 0;
584 } else {
3f63e290 585 str = "SPACE WARP!!!";
384a101e
SL
586 penalty += loot/PENALTY;
587 }
588 for(j=0;j<3;j++){
589 clear();
590 delay(5);
591 aprintf(&p,str);
592 delay(10);
593 }
594 setup();
595 winnings(cashvalue);
596}
597snap()
598{
599 struct point p;
600 int i;
601
602 if(you.line < 3){
603 pchar(point(&p,you.col,0),'-');
604 }
605 if(you.line > lcnt-4){
606 pchar(point(&p,you.col,lcnt-1),'_');
607 }
608 if(you.col < 10){
609 pchar(point(&p,0,you.line),'(');
610 }
611 if(you.col > ccnt-10){
612 pchar(point(&p,ccnt-1,you.line),')');
613 }
614 if (! stretch(&money)) if (! stretch(&finish)) delay(10);
615 if(you.line < 3){
616 point(&p,you.col,0);
617 remove(&p);
618 }
619 if(you.line > lcnt-4){
620 point(&p,you.col,lcnt-1);
621 remove(&p);
622 }
623 if(you.col < 10){
624 point(&p,0,you.line);
625 remove(&p);
626 }
627 if(you.col > ccnt-10){
628 point(&p,ccnt-1,you.line);
629 remove(&p);
630 }
631 fflush(stdout);
632}
633stretch(ps)
634struct point *ps;{
635 struct point p;
3f63e290 636
384a101e
SL
637 point(&p,you.col,you.line);
638 if(abs(ps->col-you.col) < 6){
639 if(you.line < ps->line){
640 for (p.line = you.line+1;p.line <= ps->line;p.line++)
641 pchar(&p,'v');
642 delay(10);
643 for (;p.line > you.line;p.line--)
644 remove(&p);
645 } else {
646 for (p.line = you.line-1;p.line >= ps->line;p.line--)
647 pchar(&p,'^');
648 delay(10);
649 for (;p.line < you.line;p.line++)
650 remove(&p);
651 }
652 return(1);
653 } else if(abs(ps->line-you.line) < 3){
654 p.line = you.line;
655 if(you.col < ps->col){
656 for (p.col = you.col+1;p.col <= ps->col;p.col++)
657 pchar(&p,'>');
658 delay(10);
659 for (;p.col > you.col;p.col--)
660 remove(&p);
661 } else {
662 for (p.col = you.col-1;p.col >= ps->col;p.col--)
663 pchar(&p,'<');
664 delay(10);
665 for (;p.col < you.col;p.col++)
666 remove(&p);
667 }
668 return(1);
669 }
670 return(0);
671}
672
673surround(ps)
674struct point *ps;{
675 struct point x;
676 int i,j;
677
678 if(ps->col == 0)ps->col++;
679 if(ps->line == 0)ps->line++;
680 if(ps->line == LINES -1)ps->line--;
681 if(ps->col == COLUMNS -1)ps->col--;
682 aprintf(point(&x,ps->col-1,ps->line-1),"/*\\\r* *\r\\*/");
683 for (j=0;j<20;j++){
684 pchar(ps,'@');
685 delay(1);
686 pchar(ps,' ');
687 delay(1);
688 }
689 if (post(cashvalue,1)) {
690 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
691 delay(6);
692 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.-\r\\_/");
693 delay(6);
694 }
695 aprintf(point(&x,ps->col-1,ps->line-1)," \ro.o\r\\_/");
696}
697win(ps)
698struct point *ps;
699{
700 struct point x;
701 int j,k;
702 int boxsize; /* actually diameter of box, not radius */
703
704 boxsize = fast ? 10 : 4;
705 point(&x,ps->col,ps->line);
706 for(j=1;j<boxsize;j++){
707 for(k=0;k<j;k++){
708 pchar(&x,'#');
709 x.line--;
710 }
711 for(k=0;k<j;k++){
712 pchar(&x,'#');
713 x.col++;
714 }
715 j++;
716 for(k=0;k<j;k++){
717 pchar(&x,'#');
718 x.line++;
719 }
720 for(k=0;k<j;k++){
721 pchar(&x,'#');
722 x.col--;
723 }
724 }
725 fflush(stdout);
726}
727
728pushsnake()
729{
730 int i, bonus;
731 int issame = 0;
732
733 /*
734 * My manual says times doesn't return a value. Furthermore, the
735 * snake should get his turn every time no matter if the user is
736 * on a fast terminal with typematic keys or not.
737 * So I have taken the call to times out.
738 */
739 for(i=4; i>=0; i--)
740 if (same(&snake[i], &snake[5]))
741 issame++;
742 if (!issame)
743 pchar(&snake[5],' ');
744 for(i=4; i>=0; i--)
745 snake[i+1]= snake[i];
746 chase(&snake[0], &snake[1]);
747 pchar(&snake[1],SNAKETAIL);
748 pchar(&snake[0],SNAKEHEAD);
749 for(i=0; i<6; i++)
750 {
751 if (same(&snake[i],&you))
752 {
753 surround(&you);
754 i = (cashvalue) % 10;
755 bonus = ((rand()>>8) & 0377)% 10;
756 ll();
757 printf("%d\n", bonus);
758 delay(30);
759 if (bonus == i) {
760 spacewarp(1);
761 logit("bonus");
762 flushi();
763 return(1);
764 }
765 if ( loot >= penalty ){
766 printf("You and your $%d have been eaten\n",cashvalue);
767 } else {
768 printf("The snake ate you. You owe $%d.\n",-cashvalue);
769 }
770 logit("eaten");
771 length(moves);
772 done();
773 }
774 }
775 return(0);
776}
777
778remove(sp)
779struct point *sp;
780{
781 int j;
782
783 if (same(sp,&money)) {
784 pchar(sp,TREASURE);
785 return(2);
786 }
787 if (same(sp,&finish)) {
788 pchar(sp,GOAL);
789 return(3);
790 }
791 if (same(sp,&snake[0])) {
792 pchar(sp,SNAKEHEAD);
793 return(4);
794 }
795 for(j=1;j<6;j++){
796 if(same(sp,&snake[j])){
797 pchar(sp,SNAKETAIL);
798 return(4);
799 }
800 }
801 if ((sp->col < 4) && (sp->line == 0)){
802 winnings(cashvalue);
803 if((you.line == 0) && (you.col < 4)) pchar(&you,ME);
804 return(5);
805 }
806 if (same(sp,&you)) {
807 pchar(sp,ME);
808 return(1);
809 }
810 pchar(sp,' ');
811 return(0);
812}
813winnings(won)
814int won;
815{
816 struct point p;
817
818 p.line = p.col = 1;
819 if(won>0){
820 move(&p);
821 printf("$%d",won);
822 }
823}
824
825stop(){
826 signal(SIGINT,1);
827 ll();
828 length(moves);
829 done();
830}
831
832suspend()
833{
834 char *sh;
835
3f63e290 836 ll();
384a101e 837 cook();
384a101e 838 kill(getpid(), SIGTSTP);
384a101e
SL
839 raw();
840 setup();
841 winnings(cashvalue);
842}
843
844length(num)
845int num;
846{
847 printf("You made %d moves.\n",num);
848}
849
850logit(msg)
851char *msg;
852{
853 FILE *logfile;
854 long t;
855
0f528257 856 if ((logfile=fopen(_PATH_LOGFILE, "a")) != NULL) {
384a101e
SL
857 time(&t);
858 fprintf(logfile, "%s $%d %dx%d %s %s", getlogin(), cashvalue, lcnt, ccnt, msg, ctime(&t));
859 fclose(logfile);
860 }
861}