1 #include <curses.h>
2 #include "sokoban.h"
3 #include <stdio.h>
4 
5 extern char  *strrchr(), *getlogin(), *getpass();
6 extern short readscreen(), play(), outputscore(), getuserlevel(),
7 	     newscore(), restoregame(), score();
8 
9 short scoring = 1;
10 short level, packets, savepack, moves, pushes, rows, cols;
11 short scorelevel, scoremoves, scorepushes;
12 char  map[MAXROW+1][MAXCOL+1];
13 POS   ppos;
14 char  *username, *prgname;
15 
16 static short optshowscore = 0,
17 	     optmakescore = 0,
18              optrestore = 0,
19 	     optlevel = 0;
20 static short superuser = 0;
21 
22 static short userlevel;
23 
main(argc,argv)24 main( argc, argv)
25 short argc;
26 char *argv[];
27 {
28    short ret, ret2;
29 
30    scorelevel = 0;
31    moves = pushes = packets = savepack = 0;
32    if( (prgname = strrchr( argv[0], '/')) == NULL)
33       prgname = argv[0];
34    else prgname++;
35    if( (username = getlogin("SOKNAM")) == NULL)
36       ret = E_NOUSER;
37    else {
38       superuser = (strcmp( username, SUPERUSER) == 0);
39       if( (ret = checkcmdline( argc, argv)) == 0) {
40          if( optshowscore)
41 	    ret = outputscore();
42          else if( optmakescore) {
43 	    if( superuser) ret = newscore();
44 	    else ret = E_NOSUPER;
45 	 }
46 	 else if( optrestore) {
47 	    ret = restoregame();
48 	 }
49          else if( (ret = getuserlevel( &userlevel)) == 0) {
50             if( optlevel > 0) {
51 	       if( superuser) {
52 	          level = optlevel;
53 		  scoring = 0;
54 	       }
55 	       else if( userlevel < optlevel)
56 	          ret = E_LEVELTOOHIGH;
57 	       else level = optlevel;
58 	    }
59 	    else level = userlevel;
60          }
61       }
62    }
63    if( ret == 0)
64       ret = gameloop();
65    errmess( ret);
66    if( scorelevel && scoring) {
67       ret2 = score();
68       errmess( ret2);
69    }
70    exit( ret);
71 }
72 
checkcmdline(argc,argv)73 checkcmdline( argc, argv)
74 short argc;
75 char *argv[];
76 {
77    short ret = 0;
78 
79    if( argc > 1)
80       if( (argc == 2) && (argv[1][0] == '-')) {
81 	 if( (argv[1][1] == 's') && (argv[1][2] == '\0'))
82 	    optshowscore = 1;
83 	 else if( (argv[1][1] == 'c') && (argv[1][2] == '\0'))
84 	    optmakescore = 1;
85 	 else if( (argv[1][1] == 'r') && (argv[1][2] == '\0'))
86 	    optrestore = 1;
87 	 else if( (optlevel = atoi( &(argv[1][1]))) == 0)
88 	    ret = E_USAGE;
89       }
90       else ret = E_USAGE;
91    return( ret);
92 }
93 
gameloop()94 gameloop() {
95 
96    short ret = 0;
97 
98    initscr(); cbreak(); noecho();
99    if( ! optrestore) ret = readscreen();
100    while( ret == 0) {
101       if( (ret = play()) == 0) {
102          level++;
103          moves = pushes = packets = savepack = 0;
104          ret = readscreen();
105       }
106    }
107    clear(); refresh();
108    nocbreak(); echo(); endwin();
109    return( ret);
110 }
111 
112 char *message[] = {
113    "illegal error number",
114    "cannot open screen file",
115    "more than one player position in screen file",
116    "illegal char in screen file",
117    "no player position in screenfile",
118    "too much rows in screen file",
119    "too much columns in screenfile",
120    "quit the game",
121    NULL,			/* errmessage deleted */
122    "cannot get your username",
123    "cannot open savefile",
124    "error writing to savefile",
125    "cannot stat savefile",
126    "error reading savefile",
127    "cannot restore, your savefile has been altered",
128    "game saved",
129    "too much users in score table",
130    "cannot open score file",
131    "error reading scorefile",
132    "error writing scorefile",
133    "illegal command line syntax",
134    "illegal password",
135    "level number too big in command line",
136    "only superuser is allowed to make a new score table",
137    "cannot find file to restore"
138 };
139 
errmess(ret)140 errmess( ret)
141 register short ret;
142 {
143    if( ret != E_ENDGAME) {
144       fprintf( stderr, "%s: ", prgname);
145       switch( ret) {
146          case E_FOPENSCREEN: case E_PLAYPOS1:   case E_ILLCHAR:
147 	 case E_PLAYPOS2:    case E_TOMUCHROWS: case E_TOMUCHCOLS:
148 	 case E_ENDGAME:     case E_NOUSER:
149 	 case E_FOPENSAVE:   case E_WRITESAVE:  case E_STATSAVE:
150 	 case E_READSAVE:    case E_ALTERSAVE:  case E_SAVED:
151 	 case E_TOMUCHSE:    case E_FOPENSCORE: case E_READSCORE:
152 	 case E_WRITESCORE:  case E_USAGE:	case E_ILLPASSWORD:
153 	 case E_LEVELTOOHIGH: case E_NOSUPER:	case E_NOSAVEFILE:
154 			     fprintf( stderr, "%s\n", message[ret]);
155                              break;
156          default:            fprintf( stderr, "%s\n", message[0]);
157                              break;
158       }
159       if( ret == E_USAGE) usage();
160    }
161 }
162 
163 static char *usagestr[] = {
164    "           -c:    create new score table (superuser only)\n",
165    "           -r:    restore saved game\n",
166    "           -s:    show score table\n",
167    "           -<nn>: play this level (<nn> must be greater 0)\n",
168    NULL
169 };
170 
usage()171 usage() {
172 
173    register short i;
174 
175    fprintf( stderr, "Usage: %s [-{s|c|r|<nn>}]\n\n", prgname);
176    for( i = 0; usagestr[i] != NULL; i++)
177       fprintf( stderr, "%s", usagestr[i]);
178 }
179