132689Sbostic /*
2*60842Sbostic * Copyright (c) 1988, 1993
3*60842Sbostic * The Regents of the University of California. All rights reserved.
436704Sbostic *
536704Sbostic * This code is derived from software contributed to Berkeley by
636704Sbostic * Timothy C. Stoehr.
736704Sbostic *
842595Sbostic * %sccs.include.redist.c%
936704Sbostic */
1036704Sbostic
1136704Sbostic #ifndef lint
12*60842Sbostic static char sccsid[] = "@(#)machdep.c 8.1 (Berkeley) 05/31/93";
1336704Sbostic #endif /* not lint */
1436704Sbostic
1536704Sbostic /*
1632689Sbostic * machdep.c
1732689Sbostic *
1832689Sbostic * This source herein may be modified and/or distributed by anybody who
1932689Sbostic * so desires, with the following restrictions:
2032689Sbostic * 1.) No portion of this notice shall be removed.
2132689Sbostic * 2.) Credit shall not be taken for the creation of this source.
2232689Sbostic * 3.) This code is not to be traded, sold, or used for personal
2332689Sbostic * gain or profit.
2432689Sbostic *
2532689Sbostic */
2632689Sbostic
2732689Sbostic /* Included in this file are all system dependent routines. Extensive use
2832689Sbostic * of #ifdef's will be used to compile the appropriate code on each system:
2932689Sbostic *
3032689Sbostic * UNIX: all UNIX systems.
3132689Sbostic * UNIX_BSD4_2: UNIX BSD 4.2 and later, UTEK, (4.1 BSD too?)
3232689Sbostic * UNIX_SYSV: UNIX system V
3332689Sbostic * UNIX_V7: UNIX version 7
3432689Sbostic *
3532689Sbostic * All UNIX code should be included between the single "#ifdef UNIX" at the
3632689Sbostic * top of this file, and the "#endif" at the bottom.
3732689Sbostic *
3832689Sbostic * To change a routine to include a new UNIX system, simply #ifdef the
3932689Sbostic * existing routine, as in the following example:
4032689Sbostic *
4132689Sbostic * To make a routine compatible with UNIX system 5, change the first
4232689Sbostic * function to the second:
4332689Sbostic *
4432689Sbostic * md_function()
4532689Sbostic * {
4632689Sbostic * code;
4732689Sbostic * }
4832689Sbostic *
4932689Sbostic * md_function()
5032689Sbostic * {
5132689Sbostic * #ifdef UNIX_SYSV
5232689Sbostic * sys5code;
5332689Sbostic * #else
5432689Sbostic * code;
5532689Sbostic * #endif
5632689Sbostic * }
5732689Sbostic *
5832689Sbostic * Appropriate variations of this are of course acceptible.
5932689Sbostic * The use of "#elseif" is discouraged because of non-portability.
6032689Sbostic * If the correct #define doesn't exist, "UNIX_SYSV" in this case, make it up
6132689Sbostic * and insert it in the list at the top of the file. Alter the CFLAGS
6232689Sbostic * in you Makefile appropriately.
6332689Sbostic *
6432689Sbostic */
6532689Sbostic
6632689Sbostic #ifdef UNIX
6732689Sbostic
6832689Sbostic #include <stdio.h>
6932689Sbostic #include <sys/types.h>
7032689Sbostic #include <sys/file.h>
7132689Sbostic #include <sys/stat.h>
7232690Sbostic #include <pwd.h>
7332689Sbostic
7432689Sbostic #ifdef UNIX_BSD4_2
7532689Sbostic #include <sys/time.h>
7632689Sbostic #include <sgtty.h>
7732689Sbostic #endif
7832689Sbostic
7932689Sbostic #ifdef UNIX_SYSV
8032689Sbostic #include <time.h>
8132689Sbostic #include <termio.h>
8232689Sbostic #endif
8332689Sbostic
8432689Sbostic #include <signal.h>
8532689Sbostic #include "rogue.h"
8641325Sbostic #include "pathnames.h"
8732689Sbostic
8832689Sbostic /* md_slurp:
8932689Sbostic *
9032689Sbostic * This routine throws away all keyboard input that has not
9132689Sbostic * yet been read. It is used to get rid of input that the user may have
9232689Sbostic * typed-ahead.
9332689Sbostic *
9432689Sbostic * This function is not necessary, so it may be stubbed. The might cause
9532689Sbostic * message-line output to flash by because the game has continued to read
9632689Sbostic * input without waiting for the user to read the message. Not such a
9732689Sbostic * big deal.
9832689Sbostic */
9932689Sbostic
md_slurp()10032689Sbostic md_slurp()
10132689Sbostic {
10246279Sbostic (void)fpurge(stdin);
10332689Sbostic }
10432689Sbostic
10532689Sbostic /* md_control_keyboard():
10632689Sbostic *
10732689Sbostic * This routine is much like md_cbreak_no_echo_nonl() below. It sets up the
10832689Sbostic * keyboard for appropriate input. Specifically, it prevents the tty driver
10932689Sbostic * from stealing characters. For example, ^Y is needed as a command
11032689Sbostic * character, but the tty driver intercepts it for another purpose. Any
11132689Sbostic * such behavior should be stopped. This routine could be avoided if
11232689Sbostic * we used RAW mode instead of CBREAK. But RAW mode does not allow the
11332689Sbostic * generation of keyboard signals, which the program uses.
11432689Sbostic *
11532689Sbostic * The parameter 'mode' when true, indicates that the keyboard should
11632689Sbostic * be set up to play rogue. When false, it should be restored if
11732689Sbostic * necessary.
11832689Sbostic *
11932689Sbostic * This routine is not strictly necessary and may be stubbed. This may
12032689Sbostic * cause certain command characters to be unavailable.
12132689Sbostic */
12232689Sbostic
md_control_keybord(mode)12332689Sbostic md_control_keybord(mode)
12432689Sbostic boolean mode;
12532689Sbostic {
12632689Sbostic static boolean called_before = 0;
12732689Sbostic #ifdef UNIX_BSD4_2
12832689Sbostic static struct ltchars ltc_orig;
12932689Sbostic static struct tchars tc_orig;
13032689Sbostic struct ltchars ltc_temp;
13132689Sbostic struct tchars tc_temp;
13232689Sbostic #endif
13332689Sbostic #ifdef UNIX_SYSV
13432689Sbostic static struct termio _oldtty;
13532689Sbostic struct termio _tty;
13632689Sbostic #endif
13732689Sbostic
13832689Sbostic if (!called_before) {
13932689Sbostic called_before = 1;
14032689Sbostic #ifdef UNIX_BSD4_2
14132689Sbostic ioctl(0, TIOCGETC, &tc_orig);
14232689Sbostic ioctl(0, TIOCGLTC, <c_orig);
14332689Sbostic #endif
14432689Sbostic #ifdef UNIX_SYSV
14532689Sbostic ioctl(0, TCGETA, &_oldtty);
14632689Sbostic #endif
14732689Sbostic }
14832689Sbostic #ifdef UNIX_BSD4_2
14932689Sbostic ltc_temp = ltc_orig;
15032689Sbostic tc_temp = tc_orig;
15132689Sbostic #endif
15232689Sbostic #ifdef UNIX_SYSV
15332689Sbostic _tty = _oldtty;
15432689Sbostic #endif
15532689Sbostic
15632689Sbostic if (!mode) {
15732689Sbostic #ifdef UNIX_BSD4_2
15832689Sbostic ltc_temp.t_suspc = ltc_temp.t_dsuspc = -1;
15932689Sbostic ltc_temp.t_rprntc = ltc_temp.t_flushc = -1;
16032689Sbostic ltc_temp.t_werasc = ltc_temp.t_lnextc = -1;
16132689Sbostic tc_temp.t_startc = tc_temp.t_stopc = -1;
16232689Sbostic #endif
16332689Sbostic #ifdef UNIX_SYSV
16432689Sbostic _tty.c_cc[VSWTCH] = CNSWTCH;
16532689Sbostic #endif
16632689Sbostic }
16732689Sbostic #ifdef UNIX_BSD4_2
16832689Sbostic ioctl(0, TIOCSETC, &tc_temp);
16932689Sbostic ioctl(0, TIOCSLTC, <c_temp);
17032689Sbostic #endif
17132689Sbostic #ifdef UNIX_SYSV
17232689Sbostic ioctl(0, TCSETA, &_tty);
17332689Sbostic #endif
17432689Sbostic }
17532689Sbostic
17632689Sbostic /* md_heed_signals():
17732689Sbostic *
17832689Sbostic * This routine tells the program to call particular routines when
17932689Sbostic * certain interrupts/events occur:
18032689Sbostic *
18132689Sbostic * SIGINT: call onintr() to interrupt fight with monster or long rest.
18232689Sbostic * SIGQUIT: call byebye() to check for game termination.
18332689Sbostic * SIGHUP: call error_save() to save game when terminal hangs up.
18432689Sbostic *
18532689Sbostic * On VMS, SIGINT and SIGQUIT correspond to ^C and ^Y.
18632689Sbostic *
18732689Sbostic * This routine is not strictly necessary and can be stubbed. This will
18832689Sbostic * mean that the game cannot be interrupted properly with keyboard
18932689Sbostic * input, this is not usually critical.
19032689Sbostic */
19132689Sbostic
md_heed_signals()19232689Sbostic md_heed_signals()
19332689Sbostic {
19432689Sbostic signal(SIGINT, onintr);
19532689Sbostic signal(SIGQUIT, byebye);
19632689Sbostic signal(SIGHUP, error_save);
19732689Sbostic }
19832689Sbostic
19932689Sbostic /* md_ignore_signals():
20032689Sbostic *
20132689Sbostic * This routine tells the program to completely ignore the events mentioned
20232689Sbostic * in md_heed_signals() above. The event handlers will later be turned on
20332689Sbostic * by a future call to md_heed_signals(), so md_heed_signals() and
20432689Sbostic * md_ignore_signals() need to work together.
20532689Sbostic *
20632689Sbostic * This function should be implemented or the user risks interrupting
20732689Sbostic * critical sections of code, which could cause score file, or saved-game
20832689Sbostic * file, corruption.
20932689Sbostic */
21032689Sbostic
md_ignore_signals()21132689Sbostic md_ignore_signals()
21232689Sbostic {
21332689Sbostic signal(SIGQUIT, SIG_IGN);
21432689Sbostic signal(SIGINT, SIG_IGN);
21532689Sbostic signal(SIGHUP, SIG_IGN);
21632689Sbostic }
21732689Sbostic
21832689Sbostic /* md_get_file_id():
21932689Sbostic *
22032689Sbostic * This function returns an integer that uniquely identifies the specified
22132689Sbostic * file. It need not check for the file's existence. In UNIX, the inode
22232689Sbostic * number is used.
22332689Sbostic *
22432689Sbostic * This function is used to identify saved-game files.
22532689Sbostic */
22632689Sbostic
22732689Sbostic int
md_get_file_id(fname)22832689Sbostic md_get_file_id(fname)
22932689Sbostic char *fname;
23032689Sbostic {
23132689Sbostic struct stat sbuf;
23232689Sbostic
23332689Sbostic if (stat(fname, &sbuf)) {
23432689Sbostic return(-1);
23532689Sbostic }
23632689Sbostic return((int) sbuf.st_ino);
23732689Sbostic }
23832689Sbostic
23932689Sbostic /* md_link_count():
24032689Sbostic *
24132689Sbostic * This routine returns the number of hard links to the specified file.
24232689Sbostic *
24332689Sbostic * This function is not strictly necessary. On systems without hard links
24432689Sbostic * this routine can be stubbed by just returning 1.
24532689Sbostic */
24632689Sbostic
24732689Sbostic int
md_link_count(fname)24832689Sbostic md_link_count(fname)
24932689Sbostic char *fname;
25032689Sbostic {
25132689Sbostic struct stat sbuf;
25232689Sbostic
25332689Sbostic stat(fname, &sbuf);
25432689Sbostic return((int) sbuf.st_nlink);
25532689Sbostic }
25632689Sbostic
25732689Sbostic /* md_gct(): (Get Current Time)
25832689Sbostic *
25932689Sbostic * This function returns the current year, month(1-12), day(1-31), hour(0-23),
26032689Sbostic * minute(0-59), and second(0-59). This is used for identifying the time
26132689Sbostic * at which a game is saved.
26232689Sbostic *
26332689Sbostic * This function is not strictly necessary. It can be stubbed by returning
26432689Sbostic * zeros instead of the correct year, month, etc. If your operating
26532689Sbostic * system doesn't provide all of the time units requested here, then you
26632689Sbostic * can provide only those that it does, and return zeros for the others.
26732689Sbostic * If you cannot provide good time values, then users may be able to copy
26832689Sbostic * saved-game files and play them.
26932689Sbostic */
27032689Sbostic
27132689Sbostic md_gct(rt_buf)
27232689Sbostic struct rogue_time *rt_buf;
27332689Sbostic {
27432689Sbostic struct tm *t, *localtime();
27532689Sbostic long seconds;
27632689Sbostic
27732689Sbostic time(&seconds);
27832689Sbostic t = localtime(&seconds);
27932689Sbostic
28032689Sbostic rt_buf->year = t->tm_year;
28132689Sbostic rt_buf->month = t->tm_mon + 1;
28232689Sbostic rt_buf->day = t->tm_mday;
28332689Sbostic rt_buf->hour = t->tm_hour;
28432689Sbostic rt_buf->minute = t->tm_min;
28532689Sbostic rt_buf->second = t->tm_sec;
28632689Sbostic }
28732689Sbostic
28832689Sbostic /* md_gfmt: (Get File Modification Time)
28932689Sbostic *
29032689Sbostic * This routine returns a file's date of last modification in the same format
29132689Sbostic * as md_gct() above.
29232689Sbostic *
29332689Sbostic * This function is not strictly necessary. It is used to see if saved-game
29432689Sbostic * files have been modified since they were saved. If you have stubbed the
29532689Sbostic * routine md_gct() above by returning constant values, then you may do
29632689Sbostic * exactly the same here.
29732689Sbostic * Or if md_gct() is implemented correctly, but your system does not provide
29832689Sbostic * file modification dates, you may return some date far in the past so
29932689Sbostic * that the program will never know that a saved-game file being modified.
30032689Sbostic * You may also do this if you wish to be able to restore games from
30132689Sbostic * saved-games that have been modified.
30232689Sbostic */
30332689Sbostic
md_gfmt(fname,rt_buf)30432689Sbostic md_gfmt(fname, rt_buf)
30532689Sbostic char *fname;
30632689Sbostic struct rogue_time *rt_buf;
30732689Sbostic {
30832689Sbostic struct stat sbuf;
30932689Sbostic long seconds;
31032689Sbostic struct tm *t;
31132689Sbostic
31232689Sbostic stat(fname, &sbuf);
31332689Sbostic seconds = (long) sbuf.st_mtime;
31432689Sbostic t = localtime(&seconds);
31532689Sbostic
31632689Sbostic rt_buf->year = t->tm_year;
31732689Sbostic rt_buf->month = t->tm_mon + 1;
31832689Sbostic rt_buf->day = t->tm_mday;
31932689Sbostic rt_buf->hour = t->tm_hour;
32032689Sbostic rt_buf->minute = t->tm_min;
32132689Sbostic rt_buf->second = t->tm_sec;
32232689Sbostic }
32332689Sbostic
32432689Sbostic /* md_df: (Delete File)
32532689Sbostic *
32632689Sbostic * This function deletes the specified file, and returns true (1) if the
32732689Sbostic * operation was successful. This is used to delete saved-game files
32832689Sbostic * after restoring games from them.
32932689Sbostic *
33032689Sbostic * Again, this function is not strictly necessary, and can be stubbed
33132689Sbostic * by simply returning 1. In this case, saved-game files will not be
33232689Sbostic * deleted and can be replayed.
33332689Sbostic */
33432689Sbostic
33532689Sbostic boolean
md_df(fname)33632689Sbostic md_df(fname)
33732689Sbostic char *fname;
33832689Sbostic {
33932689Sbostic if (unlink(fname)) {
34032689Sbostic return(0);
34132689Sbostic }
34232689Sbostic return(1);
34332689Sbostic }
34432689Sbostic
34532689Sbostic /* md_gln: (Get login name)
34632689Sbostic *
34732689Sbostic * This routine returns the login name of the user. This string is
34832689Sbostic * used mainly for identifying users in score files.
34932689Sbostic *
35032689Sbostic * A dummy string may be returned if you are unable to implement this
35132689Sbostic * function, but then the score file would only have one name in it.
35232689Sbostic */
35332689Sbostic
35432689Sbostic char *
md_gln()35532689Sbostic md_gln()
35632689Sbostic {
35746758Sbostic struct passwd *p;
35832689Sbostic
35932690Sbostic if (!(p = getpwuid(getuid())))
36032690Sbostic return((char *)NULL);
36132690Sbostic return(p->pw_name);
36232689Sbostic }
36332689Sbostic
36432689Sbostic /* md_sleep:
36532689Sbostic *
36632689Sbostic * This routine causes the game to pause for the specified number of
36732689Sbostic * seconds.
36832689Sbostic *
36932689Sbostic * This routine is not particularly necessary at all. It is used for
37032689Sbostic * delaying execution, which is useful to this program at some times.
37132689Sbostic */
37232689Sbostic
md_sleep(nsecs)37332689Sbostic md_sleep(nsecs)
37432689Sbostic int nsecs;
37532689Sbostic {
37632689Sbostic (void) sleep(nsecs);
37732689Sbostic }
37832689Sbostic
37932689Sbostic /* md_getenv()
38032689Sbostic *
38132689Sbostic * This routine gets certain values from the user's environment. These
38232689Sbostic * values are strings, and each string is identified by a name. The names
38332689Sbostic * of the values needed, and their use, is as follows:
38432689Sbostic *
38532689Sbostic * TERMCAP
38632689Sbostic * The name of the users's termcap file, NOT the termcap entries
38732689Sbostic * themselves. This is used ONLY if the program is compiled with
38832689Sbostic * CURSES defined (-DCURSES). Even in this case, the program need
38932689Sbostic * not find a string for TERMCAP. If it does not, it will use the
39032689Sbostic * default termcap file as returned by md_gdtcf();
39132689Sbostic * TERM
39232689Sbostic * The name of the users's terminal. This is used ONLY if the program
39332689Sbostic * is compiled with CURSES defined (-DCURSES). In this case, the string
39432689Sbostic * value for TERM must be found, or the routines in curses.c cannot
39532689Sbostic * function, and the program will quit.
39632689Sbostic * ROGUEOPTS
39732689Sbostic * A string containing the various game options. This need not be
39832689Sbostic * defined.
39932689Sbostic * HOME
40032689Sbostic * The user's home directory. This is only used when the user specifies
40132689Sbostic * '~' as the first character of a saved-game file. This string need
40232689Sbostic * not be defined.
40332689Sbostic * SHELL
40432689Sbostic * The user's favorite shell. If not found, "/bin/sh" is assumed.
40532689Sbostic *
40632689Sbostic * If your system does not provide a means of searching for these values,
40732689Sbostic * you will have to do it yourself. None of the values above really need
40832689Sbostic * to be defined except TERM when the program is compiled with CURSES
40932689Sbostic * defined. In this case, as a bare minimum, you can check the 'name'
41032689Sbostic * parameter, and if it is "TERM" find the terminal name and return that,
41132689Sbostic * else return zero. If the program is not compiled with CURSES, you can
41232689Sbostic * get by with simply always returning zero. Returning zero indicates
41332689Sbostic * that their is no defined value for the given string.
41432689Sbostic */
41532689Sbostic
41632689Sbostic char *
md_getenv(name)41732689Sbostic md_getenv(name)
41832689Sbostic char *name;
41932689Sbostic {
42032689Sbostic char *value;
42132689Sbostic char *getenv();
42232689Sbostic
42332689Sbostic value = getenv(name);
42432689Sbostic
42532689Sbostic return(value);
42632689Sbostic }
42732689Sbostic
42832689Sbostic /* md_malloc()
42932689Sbostic *
43032689Sbostic * This routine allocates, and returns a pointer to, the specified number
43132689Sbostic * of bytes. This routines absolutely MUST be implemented for your
43232689Sbostic * particular system or the program will not run at all. Return zero
43332689Sbostic * when no more memory can be allocated.
43432689Sbostic */
43532689Sbostic
43632689Sbostic char *
md_malloc(n)43732689Sbostic md_malloc(n)
43832689Sbostic int n;
43932689Sbostic {
44032689Sbostic char *malloc();
44132689Sbostic char *t;
44232689Sbostic
44332689Sbostic t = malloc(n);
44432689Sbostic return(t);
44532689Sbostic }
44632689Sbostic
44732689Sbostic /* md_gseed() (Get Seed)
44832689Sbostic *
44932689Sbostic * This function returns a seed for the random number generator (RNG). This
45032689Sbostic * seed causes the RNG to begin generating numbers at some point in it's
45132689Sbostic * sequence. Without a random seed, the RNG will generate the same set
45232689Sbostic * of numbers, and every game will start out exactly the same way. A good
45332689Sbostic * number to use is the process id, given by getpid() on most UNIX systems.
45432689Sbostic *
45532689Sbostic * You need to find some single random integer, such as:
45632689Sbostic * process id.
45732689Sbostic * current time (minutes + seconds) returned from md_gct(), if implemented.
45832689Sbostic *
45932689Sbostic * It will not help to return "get_rand()" or "rand()" or the return value of
46032689Sbostic * any pseudo-RNG. If you don't have a random number, you can just return 1,
46132689Sbostic * but this means your games will ALWAYS start the same way, and will play
46232689Sbostic * exactly the same way given the same input.
46332689Sbostic */
46432689Sbostic
md_gseed()46532689Sbostic md_gseed()
46632689Sbostic {
46732689Sbostic return(getpid());
46832689Sbostic }
46932689Sbostic
47032689Sbostic /* md_exit():
47132689Sbostic *
47232689Sbostic * This function causes the program to discontinue execution and exit.
47332689Sbostic * This function must be implemented or the program will continue to
47432689Sbostic * hang when it should quit.
47532689Sbostic */
47632689Sbostic
md_exit(status)47732689Sbostic md_exit(status)
47832689Sbostic int status;
47932689Sbostic {
48032689Sbostic exit(status);
48132689Sbostic }
48232689Sbostic
48332689Sbostic /* md_lock():
48432689Sbostic *
48541325Sbostic * This function is intended to give the user exclusive access to the score
48655779Sbostic * file. It does so by flock'ing the score file. The full path name of the
48755779Sbostic * score file should be defined for any particular site in rogue.h. The
48855779Sbostic * constants _PATH_SCOREFILE defines this file name.
48932689Sbostic *
49032689Sbostic * When the parameter 'l' is non-zero (true), a lock is requested. Otherwise
49155779Sbostic * the lock is released.
49232689Sbostic */
49332689Sbostic
md_lock(l)49432689Sbostic md_lock(l)
49532689Sbostic boolean l;
49632689Sbostic {
49755779Sbostic static int fd;
49832689Sbostic short tries;
49932689Sbostic
50032689Sbostic if (l) {
50155779Sbostic if ((fd = open(_PATH_SCOREFILE, O_RDONLY)) < 1) {
50255779Sbostic message("cannot lock score file", 0);
50355779Sbostic return;
50432689Sbostic }
50555779Sbostic for (tries = 0; tries < 5; tries++)
50655779Sbostic if (!flock(fd, LOCK_EX|LOCK_NB))
50755779Sbostic return;
50832689Sbostic } else {
50955779Sbostic (void)flock(fd, LOCK_NB);
51055779Sbostic (void)close(fd);
51132689Sbostic }
51232689Sbostic }
51332689Sbostic
51432689Sbostic /* md_shell():
51532689Sbostic *
51632689Sbostic * This function spawns a shell for the user to use. When this shell is
51732689Sbostic * terminated, the game continues. Since this program may often be run
51832689Sbostic * setuid to gain access to privileged files, care is taken that the shell
51932689Sbostic * is run with the user's REAL user id, and not the effective user id.
52032689Sbostic * The effective user id is restored after the shell completes.
52132689Sbostic */
52232689Sbostic
md_shell(shell)52332689Sbostic md_shell(shell)
52432689Sbostic char *shell;
52532689Sbostic {
52632689Sbostic long w[2];
52732689Sbostic
52832689Sbostic if (!fork()) {
52932689Sbostic int uid;
53032689Sbostic
53132689Sbostic uid = getuid();
53232689Sbostic setuid(uid);
53332689Sbostic execl(shell, shell, 0);
53432689Sbostic }
53532689Sbostic wait(w);
53632689Sbostic }
53732689Sbostic
53832689Sbostic /* If you have a viable curses/termlib library, then use it and don't bother
53932689Sbostic * implementing the routines below. And don't compile with -DCURSES.
54032689Sbostic */
54132689Sbostic
54232689Sbostic #ifdef CURSES
54332689Sbostic
54432689Sbostic /* md_cbreak_no_echo_nonl:
54532689Sbostic *
54632689Sbostic * This routine sets up some terminal characteristics. The tty-driver
54732689Sbostic * must be told to:
54832689Sbostic * 1.) Not echo input.
54932689Sbostic * 2.) Transmit input characters immediately upon typing. (cbreak mode)
55032689Sbostic * 3.) Move the cursor down one line, without changing column, and
55132689Sbostic * without generating a carriage-return, when it
55232689Sbostic * sees a line-feed. This is only necessary if line-feed is ever
55332689Sbostic * used in the termcap 'do' (cursor down) entry, in which case,
55432689Sbostic * your system should must have a way of accomplishing this.
55532689Sbostic *
55632689Sbostic * When the parameter 'on' is true, the terminal is set up as specified
55732689Sbostic * above. When this parameter is false, the terminal is restored to the
55832689Sbostic * original state.
55932689Sbostic *
56032689Sbostic * Raw mode should not to be used. Keyboard signals/events/interrupts should
56132689Sbostic * be sent, although they are not strictly necessary. See notes in
56232689Sbostic * md_heed_signals().
56332689Sbostic *
56432689Sbostic * This function must be implemented for rogue to run properly if the
56532689Sbostic * program is compiled with CURSES defined to use the enclosed curses
56632689Sbostic * emulation package. If you are not using this, then this routine is
56732689Sbostic * totally unnecessary.
56832689Sbostic *
56932689Sbostic * Notice that information is saved between calls. This is used to
57032689Sbostic * restore the terminal to an initial saved state.
57132689Sbostic *
57232689Sbostic */
57332689Sbostic
md_cbreak_no_echo_nonl(on)57432689Sbostic md_cbreak_no_echo_nonl(on)
57532689Sbostic boolean on;
57632689Sbostic {
57732689Sbostic #ifdef UNIX_BSD4_2
57832689Sbostic static struct sgttyb tty_buf;
57932689Sbostic static int tsave_flags;
58032689Sbostic
58132689Sbostic if (on) {
58232689Sbostic ioctl(0, TIOCGETP, &tty_buf);
58332689Sbostic tsave_flags = tty_buf.sg_flags;
58432689Sbostic tty_buf.sg_flags |= CBREAK;
58532689Sbostic tty_buf.sg_flags &= ~(ECHO | CRMOD); /* CRMOD: see note 3 above */
58632689Sbostic ioctl(0, TIOCSETP, &tty_buf);
58732689Sbostic } else {
58832689Sbostic tty_buf.sg_flags = tsave_flags;
58932689Sbostic ioctl(0, TIOCSETP, &tty_buf);
59032689Sbostic }
59132689Sbostic #endif
59232689Sbostic #ifdef UNIX_SYSV
59332689Sbostic struct termio tty_buf;
59432689Sbostic static struct termio tty_save;
59532689Sbostic
59632689Sbostic if (on) {
59732689Sbostic ioctl(0, TCGETA, &tty_buf);
59832689Sbostic tty_save = tty_buf;
59932689Sbostic tty_buf.c_lflag &= ~(ICANON | ECHO);
60032689Sbostic tty_buf.c_oflag &= ~ONLCR;
60132689Sbostic tty_buf.c_cc[4] = 1; /* MIN */
60232689Sbostic tty_buf.c_cc[5] = 2; /* TIME */
60332689Sbostic ioctl(0, TCSETAF, &tty_buf);
60432689Sbostic } else {
60532689Sbostic ioctl(0, TCSETAF, &tty_save);
60632689Sbostic }
60732689Sbostic #endif
60832689Sbostic }
60932689Sbostic
61032689Sbostic /* md_gdtcf(): (Get Default Termcap File)
61132689Sbostic *
61232689Sbostic * This function is called ONLY when the program is compiled with CURSES
61332689Sbostic * defined. If you use your system's curses/termlib library, this function
61432689Sbostic * won't be called. On most UNIX systems, "/etc/termcap" suffices.
61532689Sbostic *
61632689Sbostic * If their is no such termcap file, then return 0, but in that case, you
61732689Sbostic * must have a TERMCAP file returned from md_getenv("TERMCAP"). The latter
61832689Sbostic * will override the value returned from md_gdtcf(). If the program is
61932689Sbostic * compiled with CURSES defined, and md_gdtcf() returns 0, and
62032689Sbostic * md_getenv("TERMCAP") returns 0, the program will have no terminal
62132689Sbostic * capability information and will quit.
62232689Sbostic */
62332689Sbostic
62432689Sbostic char *
md_gdtcf()62532689Sbostic md_gdtcf()
62632689Sbostic {
62732689Sbostic return("/etc/termcap");
62832689Sbostic }
62932689Sbostic
63032689Sbostic /* md_tstp():
63132689Sbostic *
63232689Sbostic * This function puts the game to sleep and returns to the shell. This
63332689Sbostic * only applies to UNIX 4.2 and 4.3. For other systems, the routine should
63432689Sbostic * be provided as a do-nothing routine. md_tstp() will only be referenced
63532689Sbostic * in the code when compiled with CURSES defined.
63632689Sbostic *
63732689Sbostic */
63832689Sbostic
md_tstp()63932689Sbostic md_tstp()
64032689Sbostic {
64132689Sbostic #ifdef UNIX_BSD4_2
64232689Sbostic kill(0, SIGTSTP);
64332689Sbostic #endif
64432689Sbostic }
64532689Sbostic
64632689Sbostic #endif
64732689Sbostic
64832689Sbostic #endif
649