Mercurial > hg > early-roguelike
comparison rogue3/mdport.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
| author | edwarj4 |
|---|---|
| date | Tue, 13 Oct 2009 13:33:34 +0000 |
| parents | |
| children | 9a2c0c60c386 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:527e2150eaf0 |
|---|---|
| 1 /* | |
| 2 mdport.c - Machine Dependent Code for Porting Unix/Curses games | |
| 3 | |
| 4 Copyright (C) 2005 Nicholas J. Kisseberth | |
| 5 All rights reserved. | |
| 6 | |
| 7 Redistribution and use in source and binary forms, with or without | |
| 8 modification, are permitted provided that the following conditions | |
| 9 are met: | |
| 10 1. Redistributions of source code must retain the above copyright | |
| 11 notice, this list of conditions and the following disclaimer. | |
| 12 2. Redistributions in binary form must reproduce the above copyright | |
| 13 notice, this list of conditions and the following disclaimer in the | |
| 14 documentation and/or other materials provided with the distribution. | |
| 15 3. Neither the name(s) of the author(s) nor the names of other contributors | |
| 16 may be used to endorse or promote products derived from this software | |
| 17 without specific prior written permission. | |
| 18 | |
| 19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND | |
| 20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 22 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE | |
| 23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 25 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 26 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 27 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 28 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 29 SUCH DAMAGE. | |
| 30 */ | |
| 31 | |
| 32 #include <stdlib.h> | |
| 33 #include <string.h> | |
| 34 | |
| 35 #if defined(_WIN32) | |
| 36 #include <Windows.h> | |
| 37 #include <io.h> | |
| 38 #include <sys/locking.h> | |
| 39 #include <Lmcons.h> | |
| 40 #include <conio.h> | |
| 41 #pragma warning( disable: 4201 ) | |
| 42 #include <shlobj.h> | |
| 43 #pragma warning( default: 4201 ) | |
| 44 #include <Shlwapi.h> | |
| 45 #undef MOUSE_MOVED | |
| 46 #endif | |
| 47 | |
| 48 #include <curses.h> | |
| 49 | |
| 50 #include "mdport.h" | |
| 51 | |
| 52 #if defined(HAVE_SYS_TYPES) | |
| 53 #include <sys/types.h> | |
| 54 #endif | |
| 55 | |
| 56 #if defined(HAVE_PROCESS_H) | |
| 57 #include <process.h> | |
| 58 #endif | |
| 59 | |
| 60 #if defined(HAVE_PWD_H) | |
| 61 #include <pwd.h> | |
| 62 #endif | |
| 63 | |
| 64 #if defined(HAVE_SYS_UTSNAME) | |
| 65 #include <sys/utsname.h> | |
| 66 #endif | |
| 67 | |
| 68 #if defined(HAVE_ARPA_INET_H) | |
| 69 #include <arpa/inet.h> /* Solaris 2.8 required this for htonl() and ntohl() */ | |
| 70 #endif | |
| 71 | |
| 72 #if defined(HAVE_TERMIOS_H) | |
| 73 #include <termios.h> | |
| 74 #endif | |
| 75 | |
| 76 #if defined(HAVE_UNISTD_H) | |
| 77 #ifndef __USE_GNU | |
| 78 #define __USE_GNU | |
| 79 #include <unistd.h> | |
| 80 #undef __USE_GNU | |
| 81 #else | |
| 82 #include <unistd.h> | |
| 83 #endif | |
| 84 #endif | |
| 85 | |
| 86 #if defined(HAVE_TERM_H) | |
| 87 #include <term.h> | |
| 88 #elif defined(HAVE_NCURSES_TERM_H) | |
| 89 #include <ncurses/term.h> | |
| 90 #endif | |
| 91 | |
| 92 #if defined(HAVE_WORKING_FORK) | |
| 93 #include <sys/wait.h> | |
| 94 #endif | |
| 95 | |
| 96 #ifdef HAVE_UTMPX_H | |
| 97 #include <utmpx.h> | |
| 98 #endif | |
| 99 | |
| 100 #ifdef HAVE_ERRNO_H | |
| 101 #include <errno.h> | |
| 102 #endif | |
| 103 | |
| 104 #include <ctype.h> | |
| 105 #include <fcntl.h> | |
| 106 #include <limits.h> | |
| 107 #include <sys/stat.h> | |
| 108 #include <signal.h> | |
| 109 | |
| 110 #define NOOP(x) (x += 0) | |
| 111 | |
| 112 static int pass_ctrl_keypad = 1; | |
| 113 | |
| 114 void | |
| 115 md_init(int options) | |
| 116 { | |
| 117 #if defined(__INTERIX) | |
| 118 char *term; | |
| 119 | |
| 120 term = getenv("TERM"); | |
| 121 | |
| 122 if (term == NULL) | |
| 123 setenv("TERM","interix"); | |
| 124 #elif defined(__DJGPP__) | |
| 125 _fmode = _O_BINARY; | |
| 126 #elif defined(_WIN32) | |
| 127 _fmode = _O_BINARY; | |
| 128 #endif | |
| 129 | |
| 130 #if defined(HAVE_ESCDELAY) || defined(NCURSES_VERSION) | |
| 131 ESCDELAY=64; | |
| 132 #endif | |
| 133 | |
| 134 #if defined(DUMP) | |
| 135 md_onsignal_default(); | |
| 136 #else | |
| 137 md_onsignal_exit(); | |
| 138 #endif | |
| 139 | |
| 140 if (options & MD_STRIP_CTRL_KEYPAD) | |
| 141 pass_ctrl_keypad = 0; | |
| 142 else | |
| 143 pass_ctrl_keypad = 1; | |
| 144 } | |
| 145 | |
| 146 void | |
| 147 md_onsignal_default(void) | |
| 148 { | |
| 149 #ifdef SIGHUP | |
| 150 signal(SIGHUP, SIG_DFL); | |
| 151 #endif | |
| 152 #ifdef SIGQUIT | |
| 153 signal(SIGQUIT, SIG_DFL); | |
| 154 #endif | |
| 155 #ifdef SIGILL | |
| 156 signal(SIGILL, SIG_DFL); | |
| 157 #endif | |
| 158 #ifdef SIGTRAP | |
| 159 signal(SIGTRAP, SIG_DFL); | |
| 160 #endif | |
| 161 #ifdef SIGIOT | |
| 162 signal(SIGIOT, SIG_DFL); | |
| 163 #endif | |
| 164 #ifdef SIGEMT | |
| 165 signal(SIGEMT, SIG_DFL); | |
| 166 #endif | |
| 167 #ifdef SIGFPE | |
| 168 signal(SIGFPE, SIG_DFL); | |
| 169 #endif | |
| 170 #ifdef SIGBUS | |
| 171 signal(SIGBUS, SIG_DFL); | |
| 172 #endif | |
| 173 #ifdef SIGSEGV | |
| 174 signal(SIGSEGV, SIG_DFL); | |
| 175 #endif | |
| 176 #ifdef SIGSYS | |
| 177 signal(SIGSYS, SIG_DFL); | |
| 178 #endif | |
| 179 #ifdef SIGTERM | |
| 180 signal(SIGTERM, SIG_DFL); | |
| 181 #endif | |
| 182 } | |
| 183 | |
| 184 void | |
| 185 md_onsignal_exit(void) | |
| 186 { | |
| 187 #ifdef SIGHUP | |
| 188 signal(SIGHUP, SIG_DFL); | |
| 189 #endif | |
| 190 #ifdef SIGQUIT | |
| 191 signal(SIGQUIT, exit); | |
| 192 #endif | |
| 193 #ifdef SIGILL | |
| 194 signal(SIGILL, exit); | |
| 195 #endif | |
| 196 #ifdef SIGTRAP | |
| 197 signal(SIGTRAP, exit); | |
| 198 #endif | |
| 199 #ifdef SIGIOT | |
| 200 signal(SIGIOT, exit); | |
| 201 #endif | |
| 202 #ifdef SIGEMT | |
| 203 signal(SIGEMT, exit); | |
| 204 #endif | |
| 205 #ifdef SIGFPE | |
| 206 signal(SIGFPE, exit); | |
| 207 #endif | |
| 208 #ifdef SIGBUS | |
| 209 signal(SIGBUS, exit); | |
| 210 #endif | |
| 211 #ifdef SIGSEGV | |
| 212 signal(SIGSEGV, exit); | |
| 213 #endif | |
| 214 #ifdef SIGSYS | |
| 215 signal(SIGSYS, exit); | |
| 216 #endif | |
| 217 #ifdef SIGTERM | |
| 218 signal(SIGTERM, exit); | |
| 219 #endif | |
| 220 } | |
| 221 | |
| 222 extern void auto_save(int sig); | |
| 223 extern void endit(int sig); | |
| 224 extern void quit(int sig); | |
| 225 | |
| 226 void | |
| 227 md_onsignal_autosave(void) | |
| 228 { | |
| 229 | |
| 230 #ifdef SIGHUP | |
| 231 signal(SIGHUP, auto_save); | |
| 232 #endif | |
| 233 #ifdef SIGQUIT | |
| 234 signal(SIGQUIT, endit); | |
| 235 #endif | |
| 236 #ifdef SIGILL | |
| 237 signal(SIGILL, auto_save); | |
| 238 #endif | |
| 239 #ifdef SIGTRAP | |
| 240 signal(SIGTRAP, auto_save); | |
| 241 #endif | |
| 242 #ifdef SIGIOT | |
| 243 signal(SIGIOT, auto_save); | |
| 244 #endif | |
| 245 #ifdef SIGEMT | |
| 246 signal(SIGEMT, auto_save); | |
| 247 #endif | |
| 248 #ifdef SIGFPE | |
| 249 signal(SIGFPE, auto_save); | |
| 250 #endif | |
| 251 #ifdef SIGBUS | |
| 252 signal(SIGBUS, auto_save); | |
| 253 #endif | |
| 254 #ifdef SIGSEGV | |
| 255 signal(SIGSEGV, auto_save); | |
| 256 #endif | |
| 257 #ifdef SIGSYS | |
| 258 signal(SIGSYS, auto_save); | |
| 259 #endif | |
| 260 #ifdef SIGTERM | |
| 261 signal(SIGTERM, auto_save); | |
| 262 #endif | |
| 263 #ifdef SIGINT | |
| 264 signal(SIGINT, quit); | |
| 265 #endif | |
| 266 } | |
| 267 | |
| 268 int | |
| 269 md_hasclreol(void) | |
| 270 { | |
| 271 #if defined(clr_eol) | |
| 272 #ifdef NCURSES_VERSION | |
| 273 if (cur_term == NULL) | |
| 274 return(0); | |
| 275 if (cur_term->type.Strings == NULL) | |
| 276 return(0); | |
| 277 #endif | |
| 278 return((clr_eol != NULL) && (*clr_eol != 0)); | |
| 279 #elif defined(__PDCURSES__) | |
| 280 return(TRUE); | |
| 281 #else | |
| 282 return((CE != NULL) && (*CE != 0)); | |
| 283 #endif | |
| 284 } | |
| 285 | |
| 286 void | |
| 287 md_putchar(int c) | |
| 288 { | |
| 289 putchar(c); | |
| 290 } | |
| 291 | |
| 292 #ifdef _WIN32 | |
| 293 static int md_standout_mode = 0; | |
| 294 #endif | |
| 295 | |
| 296 void | |
| 297 md_raw_standout(void) | |
| 298 { | |
| 299 #ifdef _WIN32 | |
| 300 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; | |
| 301 HANDLE hStdout; | |
| 302 WORD fgattr,bgattr; | |
| 303 | |
| 304 if (md_standout_mode == 0) | |
| 305 { | |
| 306 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); | |
| 307 GetConsoleScreenBufferInfo(hStdout, &csbiInfo); | |
| 308 fgattr = (csbiInfo.wAttributes & 0xF); | |
| 309 bgattr = (csbiInfo.wAttributes & 0xF0); | |
| 310 SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4)); | |
| 311 md_standout_mode = 1; | |
| 312 } | |
| 313 #elif defined(SO) | |
| 314 tputs(SO,0,md_putchar); | |
| 315 fflush(stdout); | |
| 316 #endif | |
| 317 } | |
| 318 | |
| 319 void | |
| 320 md_raw_standend(void) | |
| 321 { | |
| 322 #ifdef _WIN32 | |
| 323 CONSOLE_SCREEN_BUFFER_INFO csbiInfo; | |
| 324 HANDLE hStdout; | |
| 325 WORD fgattr,bgattr; | |
| 326 | |
| 327 if (md_standout_mode == 1) | |
| 328 { | |
| 329 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); | |
| 330 GetConsoleScreenBufferInfo(hStdout, &csbiInfo); | |
| 331 fgattr = (csbiInfo.wAttributes & 0xF); | |
| 332 bgattr = (csbiInfo.wAttributes & 0xF0); | |
| 333 SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4)); | |
| 334 md_standout_mode = 0; | |
| 335 } | |
| 336 #elif defined(SE) | |
| 337 tputs(SE,0,md_putchar); | |
| 338 fflush(stdout); | |
| 339 #endif | |
| 340 } | |
| 341 | |
| 342 int | |
| 343 md_unlink_open_file(const char *file, FILE *inf) | |
| 344 { | |
| 345 #ifdef _WIN32 | |
| 346 fclose(inf); | |
| 347 (void) _chmod(file, 0600); | |
| 348 return( _unlink(file) ); | |
| 349 #else | |
| 350 return(unlink(file)); | |
| 351 #endif | |
| 352 } | |
| 353 | |
| 354 int | |
| 355 md_unlink(char *file) | |
| 356 { | |
| 357 #ifdef _WIN32 | |
| 358 (void) _chmod(file, 0600); | |
| 359 return( _unlink(file) ); | |
| 360 #else | |
| 361 return(unlink(file)); | |
| 362 #endif | |
| 363 } | |
| 364 | |
| 365 int | |
| 366 md_chmod(const char *filename, int mode) | |
| 367 { | |
| 368 #ifdef _WIN32 | |
| 369 return( _chmod(filename, mode) ); | |
| 370 #else | |
| 371 return( chmod(filename, mode) ); | |
| 372 #endif | |
| 373 } | |
| 374 | |
| 375 void | |
| 376 md_normaluser(void) | |
| 377 { | |
| 378 #if defined(HAVE_GETGID) && defined(HAVE_GETUID) | |
| 379 gid_t realgid = getgid(); | |
| 380 uid_t realuid = getuid(); | |
| 381 | |
| 382 #if defined(HAVE_SETRESGID) | |
| 383 if (setresgid(-1, realgid, realgid) != 0) { | |
| 384 #elif defined (HAVE_SETREGID) | |
| 385 if (setregid(realgid, realgid) != 0) { | |
| 386 #elif defined (HAVE_SETGID) | |
| 387 if (setgid(realgid) != 0) { | |
| 388 #else | |
| 389 if (0) { | |
| 390 #endif | |
| 391 perror("Could not drop setgid privileges. Aborting."); | |
| 392 exit(1); | |
| 393 } | |
| 394 | |
| 395 #if defined(HAVE_SETRESUID) | |
| 396 if (setresuid(-1, realuid, realuid) != 0) { | |
| 397 #elif defined(HAVE_SETREUID) | |
| 398 if (setreuid(realuid, realuid) != 0) { | |
| 399 #elif defined(HAVE_SETUID) | |
| 400 if (setuid(realuid) != 0) { | |
| 401 #else | |
| 402 if (0) { | |
| 403 #endif | |
| 404 perror("Could not drop setuid privileges. Aborting."); | |
| 405 exit(1); | |
| 406 } | |
| 407 #endif | |
| 408 } | |
| 409 | |
| 410 uid_t | |
| 411 md_getuid(void) | |
| 412 { | |
| 413 #ifdef HAVE_GETUID | |
| 414 return( getuid() ); | |
| 415 #else | |
| 416 return(42); | |
| 417 #endif | |
| 418 } | |
| 419 | |
| 420 pid_t | |
| 421 md_getpid(void) | |
| 422 { | |
| 423 #ifdef _WIN32 | |
| 424 return( _getpid() ); | |
| 425 #else | |
| 426 return( getpid() ); | |
| 427 #endif | |
| 428 } | |
| 429 | |
| 430 char * | |
| 431 md_getusername(void) | |
| 432 { | |
| 433 static char login[80]; | |
| 434 char *l = NULL; | |
| 435 #ifdef _WIN32 | |
| 436 LPSTR mybuffer; | |
| 437 DWORD size = UNLEN + 1; | |
| 438 TCHAR buffer[UNLEN + 1]; | |
| 439 | |
| 440 mybuffer = buffer; | |
| 441 GetUserName(mybuffer,&size); | |
| 442 l = mybuffer; | |
| 443 #elif defined(HAVE_GETPWUID)&& !defined(__DJGPP__) | |
| 444 struct passwd *pw; | |
| 445 | |
| 446 pw = getpwuid(getuid()); | |
| 447 | |
| 448 l = pw->pw_name; | |
| 449 #endif | |
| 450 | |
| 451 if ((l == NULL) || (*l == '\0')) | |
| 452 if ( (l = getenv("USERNAME")) == NULL ) | |
| 453 if ( (l = getenv("LOGNAME")) == NULL ) | |
| 454 if ( (l = getenv("USER")) == NULL ) | |
| 455 l = "nobody"; | |
| 456 | |
| 457 strncpy(login,l,80); | |
| 458 login[79] = 0; | |
| 459 | |
| 460 return(login); | |
| 461 } | |
| 462 | |
| 463 char * | |
| 464 md_gethomedir(void) | |
| 465 { | |
| 466 static char homedir[PATH_MAX]; | |
| 467 char *h = NULL; | |
| 468 size_t len; | |
| 469 #if defined(_WIN32) | |
| 470 TCHAR szPath[PATH_MAX]; | |
| 471 #endif | |
| 472 #if defined(_WIN32) || defined(DJGPP) | |
| 473 char slash = '\\'; | |
| 474 #else | |
| 475 char slash = '/'; | |
| 476 struct passwd *pw; | |
| 477 pw = getpwuid(getuid()); | |
| 478 | |
| 479 h = pw->pw_dir; | |
| 480 | |
| 481 if (strcmp(h,"/") == 0) | |
| 482 h = NULL; | |
| 483 #endif | |
| 484 homedir[0] = 0; | |
| 485 #ifdef _WIN32 | |
| 486 if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath))) | |
| 487 h = szPath; | |
| 488 #endif | |
| 489 | |
| 490 if ( (h == NULL) || (*h == '\0') ) | |
| 491 { | |
| 492 if ( (h = getenv("HOME")) == NULL ) | |
| 493 { | |
| 494 if ( (h = getenv("HOMEDRIVE")) == NULL) | |
| 495 h = ""; | |
| 496 else | |
| 497 { | |
| 498 strncpy(homedir,h,PATH_MAX-1); | |
| 499 homedir[PATH_MAX-1] = 0; | |
| 500 | |
| 501 if ( (h = getenv("HOMEPATH")) == NULL) | |
| 502 h = ""; | |
| 503 } | |
| 504 } | |
| 505 } | |
| 506 | |
| 507 | |
| 508 len = strlen(homedir); | |
| 509 strncat(homedir,h,PATH_MAX-len-1); | |
| 510 len = strlen(homedir); | |
| 511 | |
| 512 if ((len > 0) && (homedir[len-1] != slash)) { | |
| 513 homedir[len] = slash; | |
| 514 homedir[len+1] = 0; | |
| 515 } | |
| 516 | |
| 517 return(homedir); | |
| 518 } | |
| 519 | |
| 520 void | |
| 521 md_sleep(int s) | |
| 522 { | |
| 523 #ifdef _WIN32 | |
| 524 Sleep(s); | |
| 525 #else | |
| 526 sleep(s); | |
| 527 #endif | |
| 528 } | |
| 529 | |
| 530 char * | |
| 531 md_getshell(void) | |
| 532 { | |
| 533 static char shell[PATH_MAX]; | |
| 534 char *s = NULL; | |
| 535 #ifdef _WIN32 | |
| 536 char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE"; | |
| 537 #elif defined(__DJGPP__) | |
| 538 char *def = "C:\\COMMAND.COM"; | |
| 539 #else | |
| 540 char *def = "/bin/sh"; | |
| 541 struct passwd *pw; | |
| 542 pw = getpwuid(getuid()); | |
| 543 s = pw->pw_shell; | |
| 544 #endif | |
| 545 if ((s == NULL) || (*s == '\0')) | |
| 546 if ( (s = getenv("COMSPEC")) == NULL) | |
| 547 if ( (s = getenv("SHELL")) == NULL) | |
| 548 if ( (s = getenv("SystemRoot")) == NULL) | |
| 549 s = def; | |
| 550 | |
| 551 strncpy(shell,s,PATH_MAX); | |
| 552 shell[PATH_MAX-1] = 0; | |
| 553 | |
| 554 return(shell); | |
| 555 } | |
| 556 | |
| 557 int | |
| 558 md_shellescape(void) | |
| 559 { | |
| 560 #if defined(HAVE_WORKING_FORK) | |
| 561 int ret_status; | |
| 562 int pid; | |
| 563 void (*myquit)(int); | |
| 564 void (*myend)(int); | |
| 565 char *sh; | |
| 566 | |
| 567 sh = md_getshell(); | |
| 568 | |
| 569 while((pid = fork()) < 0) | |
| 570 sleep(1); | |
| 571 | |
| 572 if (pid == 0) /* Shell Process */ | |
| 573 { | |
| 574 /* | |
| 575 * Set back to original user, just in case | |
| 576 */ | |
| 577 md_normaluser(); | |
| 578 execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", NULL); | |
| 579 perror("No shelly"); | |
| 580 _exit(-1); | |
| 581 } | |
| 582 else /* Application */ | |
| 583 { | |
| 584 myend = signal(SIGINT, SIG_IGN); | |
| 585 #ifdef SIGQUIT | |
| 586 myquit = signal(SIGQUIT, SIG_IGN); | |
| 587 #endif | |
| 588 while (wait(&ret_status) != pid) | |
| 589 continue; | |
| 590 | |
| 591 signal(SIGINT, myquit); | |
| 592 #ifdef SIGQUIT | |
| 593 signal(SIGQUIT, myend); | |
| 594 #endif | |
| 595 } | |
| 596 return(ret_status); | |
| 597 #elif defined(HAVE__SPAWNL) | |
| 598 return((int)_spawnl(_P_WAIT,md_getshell(),"shell",NULL,0)); | |
| 599 #elif defined(HAVE_SPAWNL) | |
| 600 return ( spawnl(P_WAIT,md_getshell(),"shell",NULL,0) ); | |
| 601 #else | |
| 602 return(0); | |
| 603 #endif | |
| 604 } | |
| 605 | |
| 606 int | |
| 607 directory_exists(char *dirname) | |
| 608 { | |
| 609 struct stat sb; | |
| 610 | |
| 611 if (stat(dirname, &sb) == 0) /* path exists */ | |
| 612 return (sb.st_mode & S_IFDIR); | |
| 613 | |
| 614 return(0); | |
| 615 } | |
| 616 | |
| 617 char * | |
| 618 md_getrealname(uid_t uid) | |
| 619 { | |
| 620 static char uidstr[20]; | |
| 621 #if !defined(_WIN32) && !defined(DJGPP) | |
| 622 struct passwd *pp; | |
| 623 | |
| 624 if ((pp = getpwuid(uid)) == NULL) | |
| 625 { | |
| 626 sprintf(uidstr,"%d", uid); | |
| 627 return(uidstr); | |
| 628 } | |
| 629 else | |
| 630 return(pp->pw_name); | |
| 631 #else | |
| 632 sprintf(uidstr,"%d", uid); | |
| 633 return(uidstr); | |
| 634 #endif | |
| 635 } | |
| 636 | |
| 637 char * | |
| 638 md_getpass(char *prompt) | |
| 639 { | |
| 640 #ifndef HAVE_GETPASS | |
| 641 static char password_buffer[9]; | |
| 642 char *p = password_buffer; | |
| 643 int c, count = 0; | |
| 644 int max_length = 9; | |
| 645 | |
| 646 fflush(stdout); | |
| 647 /* If we can't prompt, abort */ | |
| 648 if (fputs(prompt, stderr) < 0) | |
| 649 { | |
| 650 *p = '\0'; | |
| 651 return NULL; | |
| 652 } | |
| 653 | |
| 654 for(;;) | |
| 655 { | |
| 656 /* Get a character with no echo */ | |
| 657 c = _getch(); | |
| 658 | |
| 659 /* Exit on interrupt (^c or ^break) */ | |
| 660 if (c == '\003' || c == 0x100) | |
| 661 exit(1); | |
| 662 | |
| 663 /* Terminate on end of line or file (^j, ^m, ^d, ^z) */ | |
| 664 if (c == '\r' || c == '\n' || c == '\004' || c == '\032') | |
| 665 break; | |
| 666 | |
| 667 /* Back up on backspace */ | |
| 668 if (c == '\b') | |
| 669 { | |
| 670 if (count) | |
| 671 count--; | |
| 672 else if (p > password_buffer) | |
| 673 p--; | |
| 674 continue; | |
| 675 } | |
| 676 | |
| 677 /* Ignore DOS extended characters */ | |
| 678 if ((c & 0xff) != c) | |
| 679 continue; | |
| 680 | |
| 681 /* Add to password if it isn't full */ | |
| 682 if (p < password_buffer + max_length - 1) | |
| 683 *p++ = (char) c; | |
| 684 else | |
| 685 count++; | |
| 686 } | |
| 687 *p = '\0'; | |
| 688 | |
| 689 fputc('\n', stderr); | |
| 690 | |
| 691 return password_buffer; | |
| 692 #else | |
| 693 return( getpass(prompt) ); | |
| 694 #endif | |
| 695 } | |
| 696 | |
| 697 int | |
| 698 md_erasechar(void) | |
| 699 { | |
| 700 #ifdef HAVE_ERASECHAR | |
| 701 return( erasechar() ); /* process erase character */ | |
| 702 #elif defined(VERASE) | |
| 703 return(_tty.c_cc[VERASE]); /* process erase character */ | |
| 704 #else | |
| 705 return(_tty.sg_erase); /* process erase character */ | |
| 706 #endif | |
| 707 } | |
| 708 | |
| 709 int | |
| 710 md_killchar(void) | |
| 711 { | |
| 712 #ifdef HAVE_KILLCHAR | |
| 713 return( killchar() ); | |
| 714 #elif defined(VKILL) | |
| 715 return(_tty.c_cc[VKILL]); | |
| 716 #else | |
| 717 return(_tty.sg_kill); | |
| 718 #endif | |
| 719 } | |
| 720 | |
| 721 int | |
| 722 md_dsuspchar(void) | |
| 723 { | |
| 724 #if defined(VDSUSP) /* POSIX has priority */ | |
| 725 struct termios attr; | |
| 726 tcgetattr(STDIN_FILENO, &attr); | |
| 727 return( attr.c_cc[VDSUSP] ); | |
| 728 #elif defined(TIOCGLTC) | |
| 729 struct ltchars ltc; | |
| 730 ioctl(1, TIOCGLTC, <c); | |
| 731 return(ltc.t_dsuspc); | |
| 732 #elif defined(_POSIX_VDISABLE) | |
| 733 return(_POSIX_VDISABLE); | |
| 734 #else | |
| 735 return(0); | |
| 736 #endif | |
| 737 } | |
| 738 | |
| 739 int | |
| 740 md_setdsuspchar(int c) | |
| 741 { | |
| 742 #if defined(VDSUSP) /* POSIX has priority */ | |
| 743 struct termios attr; | |
| 744 tcgetattr(STDIN_FILENO, &attr); | |
| 745 attr.c_cc[VDSUSP] = c; | |
| 746 tcgetattr(STDIN_FILENO, &attr); | |
| 747 #elif defined(TIOCSLTC) | |
| 748 struct ltchars ltc; | |
| 749 ioctl(1, TIOCGLTC, <c); | |
| 750 ltc.t_dsuspc = c; | |
| 751 ioctl(1, TIOCSLTC, <c); | |
| 752 #else | |
| 753 NOOP(c); | |
| 754 #endif | |
| 755 return(0); | |
| 756 } | |
| 757 | |
| 758 int | |
| 759 md_suspchar(void) | |
| 760 { | |
| 761 #if defined(VSUSP) /* POSIX has priority */ | |
| 762 struct termios attr; | |
| 763 tcgetattr(STDIN_FILENO, &attr); | |
| 764 return( attr.c_cc[VSUSP] ); | |
| 765 #elif defined(TIOCGLTC) | |
| 766 struct ltchars ltc; | |
| 767 ioctl(1, TIOCGLTC, <c); | |
| 768 return(ltc.t_suspc); | |
| 769 #elif defined(_POSIX_VDISABLE) | |
| 770 return(_POSIX_VDISABLE); | |
| 771 #else | |
| 772 return(0); | |
| 773 #endif | |
| 774 } | |
| 775 | |
| 776 int | |
| 777 md_setsuspchar(int c) | |
| 778 { | |
| 779 #if defined(VSUSP) /* POSIX has priority */ | |
| 780 struct termios attr; | |
| 781 tcgetattr(STDIN_FILENO, &attr); | |
| 782 attr.c_cc[VSUSP] = c; | |
| 783 tcgetattr(STDIN_FILENO, &attr); | |
| 784 #elif defined(TIOCSLTC) | |
| 785 struct ltchars ltc; | |
| 786 ioctl(1, TIOCGLTC, <c); | |
| 787 ltc.t_suspc = c; | |
| 788 ioctl(1, TIOCSLTC, <c); | |
| 789 #else | |
| 790 NOOP(c); | |
| 791 #endif | |
| 792 | |
| 793 return(0); | |
| 794 } | |
| 795 | |
| 796 /* | |
| 797 Cursor/Keypad Support | |
| 798 | |
| 799 Sadly Cursor/Keypad support is less straightforward than it should be. | |
| 800 | |
| 801 The various terminal emulators/consoles choose to differentiate the | |
| 802 cursor and keypad keys (with modifiers) in different ways (if at all!). | |
| 803 Furthermore they use different code set sequences for each key only | |
| 804 a subset of which the various curses libraries recognize. Partly due | |
| 805 to incomplete termcap/terminfo entries and partly due to inherent | |
| 806 limitations of those terminal capability databases. | |
| 807 | |
| 808 I give curses first crack at decoding the sequences. If it fails to decode | |
| 809 it we check for common ESC-prefixed sequences. | |
| 810 | |
| 811 All cursor/keypad results are translated into standard rogue movement | |
| 812 commands. | |
| 813 | |
| 814 Unmodified keys are translated to walk commands: hjklyubn | |
| 815 Modified (shift,control,alt) are translated to run commands: HJKLYUBN | |
| 816 | |
| 817 Console and supported (differentiated) keys | |
| 818 Interix: Cursor Keys, Keypad, Ctl-Keypad | |
| 819 Cygwin: Cursor Keys, Keypad, Alt-Cursor Keys | |
| 820 MSYS: Cursor Keys, Keypad, Ctl-Cursor Keys, Ctl-Keypad | |
| 821 Win32: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad | |
| 822 DJGPP: Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad | |
| 823 | |
| 824 Interix Console (raw, ncurses) | |
| 825 ============================== | |
| 826 normal shift ctrl alt | |
| 827 ESC [D, ESC F^, ESC [D, ESC [D /# Left #/ | |
| 828 ESC [C, ESC F$, ESC [C, ESC [C /# Right #/ | |
| 829 ESC [A, ESC F-, local win, ESC [A /# Up #/ | |
| 830 ESC [B, ESC F+, local win, ESC [B /# Down #/ | |
| 831 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/ | |
| 832 ESC [S, local win, ESC [S, ESC [S /# Page Up #/ | |
| 833 ESC [T, local win, ESC [T, ESC [T /# Page Down #/ | |
| 834 ESC [U, ESC [U, ESC [U, ESC [U /# End #/ | |
| 835 ESC [D, ESC F^, ESC [D, O /# Keypad Left #/ | |
| 836 ESC [C, ESC F$, ESC [C, O /# Keypad Right #/ | |
| 837 ESC [A, ESC [A, ESC [-1, O /# Keypad Up #/ | |
| 838 ESC [B, ESC [B, ESC [-2, O /# Keypad Down #/ | |
| 839 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/ | |
| 840 ESC [S, ESC [S, ESC [-19, O /# Keypad PgUp #/ | |
| 841 ESC [T, ESC [T, ESC [-20, O /# Keypad PgDn #/ | |
| 842 ESC [U, ESC [U, ESC [-21, O /# Keypad End #/ | |
| 843 nothing, nothing, nothing, O /# Kaypad 5 #/ | |
| 844 | |
| 845 Interix Console (term=interix, ncurses) | |
| 846 ============================== | |
| 847 KEY_LEFT, ESC F^, KEY_LEFT, KEY_LEFT /# Left #/ | |
| 848 KEY_RIGHT, ESC F$, KEY_RIGHT, KEY_RIGHT /# Right #/ | |
| 849 KEY_UP, 0x146, local win, KEY_UP /# Up #/ | |
| 850 KEY_DOWN, 0x145, local win, KEY_DOWN /# Down #/ | |
| 851 ESC [H, ESC [H, ESC [H, ESC [H /# Home #/ | |
| 852 KEY_PPAGE, local win, KEY_PPAGE, KEY_PPAGE /# Page Up #/ | |
| 853 KEY_NPAGE, local win, KEY_NPAGE, KEY_NPAGE /# Page Down #/ | |
| 854 KEY_LL, KEY_LL, KEY_LL, KEY_LL /# End #/ | |
| 855 KEY_LEFT, ESC F^, ESC [-4, O /# Keypad Left #/ | |
| 856 KEY_RIGHT, ESC F$, ESC [-3, O /# Keypad Right #/ | |
| 857 KEY_UP, KEY_UP, ESC [-1, O /# Keypad Up #/ | |
| 858 KEY_DOWN, KEY_DOWN, ESC [-2, O /# Keypad Down #/ | |
| 859 ESC [H, ESC [H, ESC [-263, O /# Keypad Home #/ | |
| 860 KEY_PPAGE, KEY_PPAGE, ESC [-19, O /# Keypad PgUp #/ | |
| 861 KEY_NPAGE, KEY_NPAGE, ESC [-20, O /# Keypad PgDn #/ | |
| 862 KEY_LL, KEY_LL, ESC [-21, O /# Keypad End #/ | |
| 863 nothing, nothing, nothing, O /# Keypad 5 #/ | |
| 864 | |
| 865 Cygwin Console (raw, ncurses) | |
| 866 ============================== | |
| 867 normal shift ctrl alt | |
| 868 ESC [D, ESC [D, ESC [D, ESC ESC [D /# Left #/ | |
| 869 ESC [C, ESC [C, ESC [C, ESC ESC [C /# Rght #/ | |
| 870 ESC [A, ESC [A, ESC [A, ESC ESC [A /# Up #/ | |
| 871 ESC [B, ESC [B, ESC [B, ESC ESC [B /# Down #/ | |
| 872 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~ /# Home #/ | |
| 873 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~ /# Page Up #/ | |
| 874 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~ /# Page Down #/ | |
| 875 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~ /# End #/ | |
| 876 ESC [D, ESC [D, ESC [D, ESC ESC [D,O /# Keypad Left #/ | |
| 877 ESC [C, ESC [C, ESC [C, ESC ESC [C,O /# Keypad Right #/ | |
| 878 ESC [A, ESC [A, ESC [A, ESC ESC [A,O /# Keypad Up #/ | |
| 879 ESC [B, ESC [B, ESC [B, ESC ESC [B,O /# Keypad Down #/ | |
| 880 ESC [1~, ESC [1~, ESC [1~, ESC ESC [1~,O /# Keypad Home #/ | |
| 881 ESC [5~, ESC [5~, ESC [5~, ESC ESC [5~,O /# Keypad PgUp #/ | |
| 882 ESC [6~, ESC [6~, ESC [6~, ESC ESC [6~,O /# Keypad PgDn #/ | |
| 883 ESC [4~, ESC [4~, ESC [4~, ESC ESC [4~,O /# Keypad End #/ | |
| 884 ESC [-71, nothing, nothing, O /# Keypad 5 #/ | |
| 885 | |
| 886 Cygwin Console (term=cygwin, ncurses) | |
| 887 ============================== | |
| 888 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260 /# Left #/ | |
| 889 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261 /# Rght #/ | |
| 890 KEY_UP, KEY_UP, KEY_UP, ESC-259 /# Up #/ | |
| 891 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258 /# Down #/ | |
| 892 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262 /# Home #/ | |
| 893 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339 /# Page Up #/ | |
| 894 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338 /# Page Down #/ | |
| 895 KEY_END, KEY_END, KEY_END, ESC-360 /# End #/ | |
| 896 KEY_LEFT, KEY_LEFT, KEY_LEFT, ESC-260,O /# Keypad Left #/ | |
| 897 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, ESC-261,O /# Keypad Right #/ | |
| 898 KEY_UP, KEY_UP, KEY_UP, ESC-259,O /# Keypad Up #/ | |
| 899 KEY_DOWN, KEY_DOWN, KEY_DOWN, ESC-258,O /# Keypad Down #/ | |
| 900 KEY_HOME, KEY_HOME, KEY_HOME, ESC-262,O /# Keypad Home #/ | |
| 901 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, ESC-339,O /# Keypad PgUp #/ | |
| 902 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, ESC-338,O /# Keypad PgDn #/ | |
| 903 KEY_END, KEY_END, KEY_END, ESC-360,O /# Keypad End #/ | |
| 904 ESC [G, nothing, nothing, O /# Keypad 5 #/ | |
| 905 | |
| 906 MSYS Console (raw, ncurses) | |
| 907 ============================== | |
| 908 normal shift ctrl alt | |
| 909 ESC OD, ESC [d, ESC Od nothing /# Left #/ | |
| 910 ESC OE, ESC [e, ESC Oe, nothing /# Right #/ | |
| 911 ESC OA, ESC [a, ESC Oa, nothing /# Up #/ | |
| 912 ESC OB, ESC [b, ESC Ob, nothing /# Down #/ | |
| 913 ESC [7~, ESC [7$, ESC [7^, nothing /# Home #/ | |
| 914 ESC [5~, local window, ESC [5^, nothing /# Page Up #/ | |
| 915 ESC [6~, local window, ESC [6^, nothing /# Page Down #/ | |
| 916 ESC [8~, ESC [8$, ESC [8^, nothing /# End #/ | |
| 917 ESC OD, ESC [d, ESC Od O /# Keypad Left #/ | |
| 918 ESC OE, ESC [c, ESC Oc, O /# Keypad Right #/ | |
| 919 ESC OA, ESC [a, ESC Oa, O /# Keypad Up #/ | |
| 920 ESC OB, ESC [b, ESC Ob, O /# Keypad Down #/ | |
| 921 ESC [7~, ESC [7$, ESC [7^, O /# Keypad Home #/ | |
| 922 ESC [5~, local window, ESC [5^, O /# Keypad PgUp #/ | |
| 923 ESC [6~, local window, ESC [6^, O /# Keypad PgDn #/ | |
| 924 ESC [8~, ESC [8$, ESC [8^, O /# Keypad End #/ | |
| 925 11, 11, 11, O /# Keypad 5 #/ | |
| 926 | |
| 927 MSYS Console (term=rxvt, ncurses) | |
| 928 ============================== | |
| 929 normal shift ctrl alt | |
| 930 KEY_LEFT, KEY_SLEFT, 514 nothing /# Left #/ | |
| 931 KEY_RIGHT, KEY_SRIGHT, 516, nothing /# Right #/ | |
| 932 KEY_UP, 518, 519, nothing /# Up #/ | |
| 933 KEY_DOWN, 511, 512, nothing /# Down #/ | |
| 934 KEY_HOME, KEY_SHOME, ESC [7^, nothing /# Home #/ | |
| 935 KEY_PPAGE, local window, ESC [5^, nothing /# Page Up #/ | |
| 936 KEY_NPAGE, local window, ESC [6^, nothing /# Page Down #/ | |
| 937 KEY_END, KEY_SEND, KEY_EOL, nothing /# End #/ | |
| 938 KEY_LEFT, KEY_SLEFT, 514 O /# Keypad Left #/ | |
| 939 KEY_RIGHT, KEY_SRIGHT, 516, O /# Keypad Right #/ | |
| 940 KEY_UP, 518, 519, O /# Keypad Up #/ | |
| 941 KEY_DOWN, 511, 512, O /# Keypad Down #/ | |
| 942 KEY_HOME, KEY_SHOME, ESC [7^, O /# Keypad Home #/ | |
| 943 KEY_PPAGE, local window, ESC [5^, O /# Keypad PgUp #/ | |
| 944 KEY_NPAGE, local window, ESC [6^, O /# Keypad PgDn #/ | |
| 945 KEY_END, KEY_SEND, KEY_EOL, O /# Keypad End #/ | |
| 946 11, 11, 11, O /# Keypad 5 #/ | |
| 947 | |
| 948 Win32 Console (raw, pdcurses) | |
| 949 DJGPP Console (raw, pdcurses) | |
| 950 ============================== | |
| 951 normal shift ctrl alt | |
| 952 260, 391, 443, 493 /# Left #/ | |
| 953 261, 400, 444, 492 /# Right #/ | |
| 954 259, 547, 480, 490 /# Up #/ | |
| 955 258, 548, 481, 491 /# Down #/ | |
| 956 262, 388, 447, 524 /# Home #/ | |
| 957 339, 396, 445, 526 /# Page Up #/ | |
| 958 338, 394, 446, 520 /# Page Down #/ | |
| 959 358, 384, 448, 518 /# End #/ | |
| 960 452, 52('4'), 511, 521 /# Keypad Left #/ | |
| 961 454, 54('6'), 513, 523 /# Keypad Right #/ | |
| 962 450, 56('8'), 515, 525 /# Keypad Up #/ | |
| 963 456, 50('2'), 509, 519 /# Keypad Down #/ | |
| 964 449, 55('7'), 514, 524 /# Keypad Home #/ | |
| 965 451, 57('9'), 516, 526 /# Keypad PgUp #/ | |
| 966 457, 51('3'), 510, 520 /# Keypad PgDn #/ | |
| 967 455, 49('1'), 508, 518 /# Keypad End #/ | |
| 968 453, 53('5'), 512, 522 /# Keypad 5 #/ | |
| 969 | |
| 970 Win32 Console (pdcurses, MSVC/MingW32) | |
| 971 DJGPP Console (pdcurses) | |
| 972 ============================== | |
| 973 normal shift ctrl alt | |
| 974 KEY_LEFT, KEY_SLEFT, CTL_LEFT, ALT_LEFT /# Left #/ | |
| 975 KEY_RIGHT, KEY_SRIGHT, CTL_RIGHT, ALT_RIGHT /# Right #/ | |
| 976 KEY_UP, KEY_SUP, CTL_UP, ALT_UP /# Up #/ | |
| 977 KEY_DOWN, KEY_SDOWN, CTL_DOWN, ALT_DOWN /# Down #/ | |
| 978 KEY_HOME, KEY_SHOME, CTL_HOME, ALT_HOME /# Home #/ | |
| 979 KEY_PPAGE, KEY_SPREVIOUS, CTL_PGUP, ALT_PGUP /# Page Up #/ | |
| 980 KEY_NPAGE, KEY_SNEXTE, CTL_PGDN, ALT_PGDN /# Page Down #/ | |
| 981 KEY_END, KEY_SEND, CTL_END, ALT_END /# End #/ | |
| 982 KEY_B1, 52('4'), CTL_PAD4, ALT_PAD4 /# Keypad Left #/ | |
| 983 KEY_B3, 54('6'), CTL_PAD6, ALT_PAD6 /# Keypad Right #/ | |
| 984 KEY_A2, 56('8'), CTL_PAD8, ALT_PAD8 /# Keypad Up #/ | |
| 985 KEY_C2, 50('2'), CTL_PAD2, ALT_PAD2 /# Keypad Down #/ | |
| 986 KEY_A1, 55('7'), CTL_PAD7, ALT_PAD7 /# Keypad Home #/ | |
| 987 KEY_A3, 57('9'), CTL_PAD9, ALT_PAD9 /# Keypad PgUp #/ | |
| 988 KEY_C3, 51('3'), CTL_PAD3, ALT_PAD3 /# Keypad PgDn #/ | |
| 989 KEY_C1, 49('1'), CTL_PAD1, ALT_PAD1 /# Keypad End #/ | |
| 990 KEY_B2, 53('5'), CTL_PAD5, ALT_PAD5 /# Keypad 5 #/ | |
| 991 | |
| 992 Windows Telnet (raw) | |
| 993 ============================== | |
| 994 normal shift ctrl alt | |
| 995 ESC [D, ESC [D, ESC [D, ESC [D /# Left #/ | |
| 996 ESC [C, ESC [C, ESC [C, ESC [C /# Right #/ | |
| 997 ESC [A, ESC [A, ESC [A, ESC [A /# Up #/ | |
| 998 ESC [B, ESC [B, ESC [B, ESC [B /# Down #/ | |
| 999 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/ | |
| 1000 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Page Up #/ | |
| 1001 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Page Down #/ | |
| 1002 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/ | |
| 1003 ESC [D, ESC [D, ESC [D, ESC [D /# Keypad Left #/ | |
| 1004 ESC [C, ESC [C, ESC [C, ESC [C /# Keypad Right #/ | |
| 1005 ESC [A, ESC [A, ESC [A, ESC [A /# Keypad Up #/ | |
| 1006 ESC [B, ESC [B, ESC [B, ESC [B /# Keypad Down #/ | |
| 1007 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/ | |
| 1008 ESC [5~, ESC [5~, ESC [5~, ESC [5~ /# Keypad PgUp #/ | |
| 1009 ESC [6~, ESC [6~, ESC [6~, ESC [6~ /# Keypad PgDn #/ | |
| 1010 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# Keypad End #/ | |
| 1011 nothing, nothing, nothing, nothing /# Keypad 5 #/ | |
| 1012 | |
| 1013 Windows Telnet (term=xterm) | |
| 1014 ============================== | |
| 1015 normal shift ctrl alt | |
| 1016 KEY_LEFT, KEY_LEFT, KEY_LEFT, KEY_LEFT /# Left #/ | |
| 1017 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, KEY_RIGHT /# Right #/ | |
| 1018 KEY_UP, KEY_UP, KEY_UP, KEY_UP /# Up #/ | |
| 1019 KEY_DOWN, KEY_DOWN, KEY_DOWN, KEY_DOWN /# Down #/ | |
| 1020 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Home #/ | |
| 1021 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Page Up #/ | |
| 1022 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Page Down #/ | |
| 1023 ESC [4~, ESC [4~, ESC [4~, ESC [4~ /# End #/ | |
| 1024 KEY_LEFT, KEY_LEFT, KEY_LEFT, O /# Keypad Left #/ | |
| 1025 KEY_RIGHT, KEY_RIGHT, KEY_RIGHT, O /# Keypad Right #/ | |
| 1026 KEY_UP, KEY_UP, KEY_UP, O /# Keypad Up #/ | |
| 1027 KEY_DOWN, KEY_DOWN, KEY_DOWN, O /# Keypad Down #/ | |
| 1028 ESC [1~, ESC [1~, ESC [1~, ESC [1~ /# Keypad Home #/ | |
| 1029 KEY_PPAGE, KEY_PPAGE, KEY_PPAGE, KEY_PPAGE /# Keypad PgUp #/ | |
| 1030 KEY_NPAGE, KEY_NPAGE, KEY_NPAGE, KEY_NPAGE /# Keypad PgDn #/ | |
| 1031 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/ | |
| 1032 ESC [-71, nothing, nothing, O /# Keypad 5 #/ | |
| 1033 | |
| 1034 PuTTY | |
| 1035 ============================== | |
| 1036 normal shift ctrl alt | |
| 1037 ESC [D, ESC [D, ESC OD, ESC [D /# Left #/ | |
| 1038 ESC [C, ESC [C, ESC OC, ESC [C /# Right #/ | |
| 1039 ESC [A, ESC [A, ESC OA, ESC [A /# Up #/ | |
| 1040 ESC [B, ESC [B, ESC OB, ESC [B /# Down #/ | |
| 1041 ESC [1~, ESC [1~, local win, ESC [1~ /# Home #/ | |
| 1042 ESC [5~, local win, local win, ESC [5~ /# Page Up #/ | |
| 1043 ESC [6~, local win, local win, ESC [6~ /# Page Down #/ | |
| 1044 ESC [4~, ESC [4~, local win, ESC [4~ /# End #/ | |
| 1045 ESC [D, ESC [D, ESC [D, O /# Keypad Left #/ | |
| 1046 ESC [C, ESC [C, ESC [C, O /# Keypad Right #/ | |
| 1047 ESC [A, ESC [A, ESC [A, O /# Keypad Up #/ | |
| 1048 ESC [B, ESC [B, ESC [B, O /# Keypad Down #/ | |
| 1049 ESC [1~, ESC [1~, ESC [1~, O /# Keypad Home #/ | |
| 1050 ESC [5~, ESC [5~, ESC [5~, O /# Keypad PgUp #/ | |
| 1051 ESC [6~, ESC [6~, ESC [6~, O /# Keypad PgDn #/ | |
| 1052 ESC [4~, ESC [4~, ESC [4~, O /# Keypad End #/ | |
| 1053 nothing, nothing, nothing, O /# Keypad 5 #/ | |
| 1054 | |
| 1055 PuTTY | |
| 1056 ============================== | |
| 1057 normal shift ctrl alt | |
| 1058 KEY_LEFT, KEY_LEFT, ESC OD, ESC KEY_LEFT /# Left #/ | |
| 1059 KEY_RIGHT KEY_RIGHT, ESC OC, ESC KEY_RIGHT /# Right #/ | |
| 1060 KEY_UP, KEY_UP, ESC OA, ESC KEY_UP /# Up #/ | |
| 1061 KEY_DOWN, KEY_DOWN, ESC OB, ESC KEY_DOWN /# Down #/ | |
| 1062 ESC [1~, ESC [1~, local win, ESC ESC [1~ /# Home #/ | |
| 1063 KEY_PPAGE local win, local win, ESC KEY_PPAGE /# Page Up #/ | |
| 1064 KEY_NPAGE local win, local win, ESC KEY_NPAGE /# Page Down #/ | |
| 1065 ESC [4~, ESC [4~, local win, ESC ESC [4~ /# End #/ | |
| 1066 ESC Ot, ESC Ot, ESC Ot, O /# Keypad Left #/ | |
| 1067 ESC Ov, ESC Ov, ESC Ov, O /# Keypad Right #/ | |
| 1068 ESC Ox, ESC Ox, ESC Ox, O /# Keypad Up #/ | |
| 1069 ESC Or, ESC Or, ESC Or, O /# Keypad Down #/ | |
| 1070 ESC Ow, ESC Ow, ESC Ow, O /# Keypad Home #/ | |
| 1071 ESC Oy, ESC Oy, ESC Oy, O /# Keypad PgUp #/ | |
| 1072 ESC Os, ESC Os, ESC Os, O /# Keypad PgDn #/ | |
| 1073 ESC Oq, ESC Oq, ESC Oq, O /# Keypad End #/ | |
| 1074 ESC Ou, ESC Ou, ESC Ou, O /# Keypad 5 #/ | |
| 1075 */ | |
| 1076 | |
| 1077 #define M_NORMAL 0 | |
| 1078 #define M_ESC 1 | |
| 1079 #define M_KEYPAD 2 | |
| 1080 #define M_TRAIL 3 | |
| 1081 | |
| 1082 #ifndef CTRL | |
| 1083 #define CTRL(ch) (ch & 0x1F) | |
| 1084 #endif | |
| 1085 | |
| 1086 int undo[5]; | |
| 1087 int uindex = -1; | |
| 1088 | |
| 1089 int | |
| 1090 reread() | |
| 1091 { | |
| 1092 int redo; | |
| 1093 | |
| 1094 if (uindex < 0) | |
| 1095 return 0; | |
| 1096 | |
| 1097 redo = undo[0]; | |
| 1098 undo[0] = undo[1]; | |
| 1099 undo[1] = undo[2]; | |
| 1100 undo[2] = undo[3]; | |
| 1101 undo[3] = undo[4]; | |
| 1102 uindex--; | |
| 1103 return redo; | |
| 1104 } | |
| 1105 | |
| 1106 void | |
| 1107 unread(int c) | |
| 1108 { | |
| 1109 if (uindex >= 4) | |
| 1110 abort(); | |
| 1111 | |
| 1112 undo[++uindex] = c; | |
| 1113 } | |
| 1114 | |
| 1115 int | |
| 1116 md_readchar(WINDOW *win) | |
| 1117 { | |
| 1118 int ch = 0; | |
| 1119 int lastch = 0; | |
| 1120 int wch = 0; | |
| 1121 int mode = M_NORMAL; | |
| 1122 int mode2 = M_NORMAL; | |
| 1123 int nodelayf = 0; | |
| 1124 int count = 0; | |
| 1125 | |
| 1126 for(;;) | |
| 1127 { | |
| 1128 if (mode == M_NORMAL && uindex >= 0) | |
| 1129 { | |
| 1130 wch = ch = reread(); | |
| 1131 break; | |
| 1132 } | |
| 1133 | |
| 1134 wch = ch = wgetch(win); | |
| 1135 | |
| 1136 if (ch == ERR) /* timed out or error */ | |
| 1137 { | |
| 1138 if (nodelayf) /* likely timed out, switch to */ | |
| 1139 { /* normal mode and block on */ | |
| 1140 mode = M_NORMAL; /* next read */ | |
| 1141 nodelayf = 0; | |
| 1142 nodelay(win,0); | |
| 1143 } | |
| 1144 else if (count > 10) /* after 10 errors assume */ | |
| 1145 auto_save(0); /* input stream is broken and */ | |
| 1146 else /* auto save and exit */ | |
| 1147 count++; | |
| 1148 | |
| 1149 continue; | |
| 1150 } | |
| 1151 | |
| 1152 count = 0; /* reset input error count */ | |
| 1153 | |
| 1154 if (mode == M_TRAIL) | |
| 1155 { | |
| 1156 if (ch == '^') /* msys console : 7,5,6,8: modified*/ | |
| 1157 ch = CTRL( toupper(lastch) ); | |
| 1158 else if (ch == '~') /* cygwin console: 1,5,6,4: normal */ | |
| 1159 ch = tolower(lastch); /* windows telnet: 1,5,6,4: normal */ | |
| 1160 /* msys console : 7,5,6,8: normal */ | |
| 1161 else if (mode2 == M_ESC) /* cygwin console: 1,5,6,4: modified*/ | |
| 1162 ch = CTRL( toupper(ch) ); | |
| 1163 else | |
| 1164 { | |
| 1165 mode = M_NORMAL; | |
| 1166 unread(ch); | |
| 1167 continue; | |
| 1168 } | |
| 1169 | |
| 1170 break; | |
| 1171 } | |
| 1172 | |
| 1173 if (mode == M_ESC) | |
| 1174 { | |
| 1175 if (ch == 27) | |
| 1176 { | |
| 1177 mode2 = M_ESC; | |
| 1178 unread(ch); | |
| 1179 continue; | |
| 1180 } | |
| 1181 | |
| 1182 if ((ch == 'F') || (ch == 'O') || (ch == '[')) | |
| 1183 { | |
| 1184 mode = M_KEYPAD; | |
| 1185 unread(ch); | |
| 1186 continue; | |
| 1187 } | |
| 1188 | |
| 1189 | |
| 1190 switch(ch) | |
| 1191 { | |
| 1192 /* Cygwin Console */ | |
| 1193 /* PuTTY */ | |
| 1194 case KEY_LEFT : ch = CTRL('H'); break; | |
| 1195 case KEY_RIGHT: ch = CTRL('L'); break; | |
| 1196 case KEY_UP : ch = CTRL('K'); break; | |
| 1197 case KEY_DOWN : ch = CTRL('J'); break; | |
| 1198 case KEY_HOME : ch = CTRL('Y'); break; | |
| 1199 case KEY_PPAGE: ch = CTRL('U'); break; | |
| 1200 case KEY_NPAGE: ch = CTRL('N'); break; | |
| 1201 case KEY_END : ch = CTRL('B'); break; | |
| 1202 | |
| 1203 default: mode = M_NORMAL; | |
| 1204 mode2 = M_NORMAL; | |
| 1205 unread(ch); | |
| 1206 continue;} | |
| 1207 | |
| 1208 break; | |
| 1209 } | |
| 1210 | |
| 1211 if (mode == M_KEYPAD) | |
| 1212 { | |
| 1213 switch(ch) | |
| 1214 { | |
| 1215 /* ESC F - Interix Console codes */ | |
| 1216 case '^': ch = CTRL('H'); break; /* Shift-Left */ | |
| 1217 case '$': ch = CTRL('L'); break; /* Shift-Right */ | |
| 1218 | |
| 1219 /* ESC [ - Interix Console codes */ | |
| 1220 case 'H': ch = 'y'; break; /* Home */ | |
| 1221 case 1: ch = CTRL('K'); break; /* Ctl-Keypad Up */ | |
| 1222 case 2: ch = CTRL('J'); break; /* Ctl-Keypad Down */ | |
| 1223 case 3: ch = CTRL('L'); break; /* Ctl-Keypad Right */ | |
| 1224 case 4: ch = CTRL('H'); break; /* Ctl-Keypad Left */ | |
| 1225 case 263: ch = CTRL('Y'); break; /* Ctl-Keypad Home */ | |
| 1226 case 19: ch = CTRL('U'); break; /* Ctl-Keypad PgUp */ | |
| 1227 case 20: ch = CTRL('N'); break; /* Ctl-Keypad PgDn */ | |
| 1228 case 21: ch = CTRL('B'); break; /* Ctl-Keypad End */ | |
| 1229 | |
| 1230 /* ESC [ - Cygwin Console codes */ | |
| 1231 case 'G': ch = '.'; break; /* Keypad 5 */ | |
| 1232 case '7': lastch = 'Y'; mode=M_TRAIL; break; /* Ctl-Home */ | |
| 1233 case '5': lastch = 'U'; mode=M_TRAIL; break; /* Ctl-PgUp */ | |
| 1234 case '6': lastch = 'N'; mode=M_TRAIL; break; /* Ctl-PgDn */ | |
| 1235 | |
| 1236 /* ESC [ - Win32 Telnet, PuTTY */ | |
| 1237 case '1': lastch = 'y'; mode=M_TRAIL; break; /* Home */ | |
| 1238 case '4': lastch = 'b'; mode=M_TRAIL; break; /* End */ | |
| 1239 | |
| 1240 /* ESC O - PuTTY */ | |
| 1241 case 'D': ch = CTRL('H'); break; | |
| 1242 case 'C': ch = CTRL('L'); break; | |
| 1243 case 'A': ch = CTRL('K'); break; | |
| 1244 case 'B': ch = CTRL('J'); break; | |
| 1245 case 't': ch = 'h'; break; | |
| 1246 case 'v': ch = 'l'; break; | |
| 1247 case 'x': ch = 'k'; break; | |
| 1248 case 'r': ch = 'j'; break; | |
| 1249 case 'w': ch = 'y'; break; | |
| 1250 case 'y': ch = 'u'; break; | |
| 1251 case 's': ch = 'n'; break; | |
| 1252 case 'q': ch = 'b'; break; | |
| 1253 case 'u': ch = '.'; break; | |
| 1254 } | |
| 1255 | |
| 1256 if (mode != M_KEYPAD) | |
| 1257 { | |
| 1258 unread(ch); | |
| 1259 continue; | |
| 1260 } | |
| 1261 } | |
| 1262 | |
| 1263 if (ch == 27) | |
| 1264 { | |
| 1265 nodelay(win,1); | |
| 1266 mode = M_ESC; | |
| 1267 nodelayf = 1; | |
| 1268 unread(ch); | |
| 1269 continue; | |
| 1270 } | |
| 1271 | |
| 1272 switch(ch) | |
| 1273 { | |
| 1274 case KEY_LEFT : ch = 'h'; break; | |
| 1275 case KEY_DOWN : ch = 'j'; break; | |
| 1276 case KEY_UP : ch = 'k'; break; | |
| 1277 case KEY_RIGHT : ch = 'l'; break; | |
| 1278 case KEY_HOME : ch = 'y'; break; | |
| 1279 case KEY_PPAGE : ch = 'u'; break; | |
| 1280 case KEY_END : ch = 'b'; break; | |
| 1281 #ifdef KEY_LL | |
| 1282 case KEY_LL : ch = 'b'; break; | |
| 1283 #endif | |
| 1284 case KEY_NPAGE : ch = 'n'; break; | |
| 1285 | |
| 1286 #ifdef KEY_B1 | |
| 1287 case KEY_B1 : ch = 'h'; break; | |
| 1288 case KEY_C2 : ch = 'j'; break; | |
| 1289 case KEY_A2 : ch = 'k'; break; | |
| 1290 case KEY_B3 : ch = 'l'; break; | |
| 1291 #endif | |
| 1292 case KEY_A1 : ch = 'y'; break; | |
| 1293 case KEY_A3 : ch = 'u'; break; | |
| 1294 case KEY_C1 : ch = 'b'; break; | |
| 1295 case KEY_C3 : ch = 'n'; break; | |
| 1296 /* next should be '.', but for problem with putty/linux */ | |
| 1297 case KEY_B2 : ch = 'u'; break; | |
| 1298 | |
| 1299 #ifdef KEY_SLEFT | |
| 1300 case KEY_SRIGHT : ch = CTRL('L'); break; | |
| 1301 case KEY_SLEFT : ch = CTRL('H'); break; | |
| 1302 #ifdef KEY_SUP | |
| 1303 case KEY_SUP : ch = CTRL('K'); break; | |
| 1304 case KEY_SDOWN : ch = CTRL('J'); break; | |
| 1305 #endif | |
| 1306 case KEY_SHOME : ch = CTRL('Y'); break; | |
| 1307 case KEY_SPREVIOUS:ch = CTRL('U'); break; | |
| 1308 case KEY_SEND : ch = CTRL('B'); break; | |
| 1309 case KEY_SNEXT : ch = CTRL('N'); break; | |
| 1310 #endif | |
| 1311 case 0x146 : ch = CTRL('K'); break; /* Shift-Up */ | |
| 1312 case 0x145 : ch = CTRL('J'); break; /* Shift-Down */ | |
| 1313 | |
| 1314 #ifdef CTL_RIGHT | |
| 1315 case CTL_RIGHT : ch = CTRL('L'); break; | |
| 1316 case CTL_LEFT : ch = CTRL('H'); break; | |
| 1317 case CTL_UP : ch = CTRL('K'); break; | |
| 1318 case CTL_DOWN : ch = CTRL('J'); break; | |
| 1319 case CTL_HOME : ch = CTRL('Y'); break; | |
| 1320 case CTL_PGUP : ch = CTRL('U'); break; | |
| 1321 case CTL_END : ch = CTRL('B'); break; | |
| 1322 case CTL_PGDN : ch = CTRL('N'); break; | |
| 1323 #endif | |
| 1324 #ifdef KEY_EOL | |
| 1325 case KEY_EOL : ch = CTRL('B'); break; | |
| 1326 #endif | |
| 1327 | |
| 1328 #ifndef CTL_PAD1 | |
| 1329 /* MSYS rxvt console */ | |
| 1330 case 511 : ch = CTRL('J'); break; /* Shift Dn */ | |
| 1331 case 512 : ch = CTRL('J'); break; /* Ctl Down */ | |
| 1332 case 514 : ch = CTRL('H'); break; /* Ctl Left */ | |
| 1333 case 516 : ch = CTRL('L'); break; /* Ctl Right*/ | |
| 1334 case 518 : ch = CTRL('K'); break; /* Shift Up */ | |
| 1335 case 519 : ch = CTRL('K'); break; /* Ctl Up */ | |
| 1336 #endif | |
| 1337 | |
| 1338 #ifdef CTL_PAD1 | |
| 1339 case CTL_PAD1 : ch = CTRL('B'); break; | |
| 1340 case CTL_PAD2 : ch = CTRL('J'); break; | |
| 1341 case CTL_PAD3 : ch = CTRL('N'); break; | |
| 1342 case CTL_PAD4 : ch = CTRL('H'); break; | |
| 1343 case CTL_PAD5 : ch = '.'; break; | |
| 1344 case CTL_PAD6 : ch = CTRL('L'); break; | |
| 1345 case CTL_PAD7 : ch = CTRL('Y'); break; | |
| 1346 case CTL_PAD8 : ch = CTRL('K'); break; | |
| 1347 case CTL_PAD9 : ch = CTRL('U'); break; | |
| 1348 #endif | |
| 1349 | |
| 1350 #ifdef ALT_RIGHT | |
| 1351 case ALT_RIGHT : ch = CTRL('L'); break; | |
| 1352 case ALT_LEFT : ch = CTRL('H'); break; | |
| 1353 case ALT_DOWN : ch = CTRL('J'); break; | |
| 1354 case ALT_HOME : ch = CTRL('Y'); break; | |
| 1355 case ALT_PGUP : ch = CTRL('U'); break; | |
| 1356 case ALT_END : ch = CTRL('B'); break; | |
| 1357 case ALT_PGDN : ch = CTRL('N'); break; | |
| 1358 #endif | |
| 1359 | |
| 1360 #ifdef ALT_PAD1 | |
| 1361 case ALT_PAD1 : ch = CTRL('B'); break; | |
| 1362 case ALT_PAD2 : ch = CTRL('J'); break; | |
| 1363 case ALT_PAD3 : ch = CTRL('N'); break; | |
| 1364 case ALT_PAD4 : ch = CTRL('H'); break; | |
| 1365 case ALT_PAD5 : ch = '.'; break; | |
| 1366 case ALT_PAD6 : ch = CTRL('L'); break; | |
| 1367 case ALT_PAD7 : ch = CTRL('Y'); break; | |
| 1368 case ALT_PAD8 : ch = CTRL('K'); break; | |
| 1369 case ALT_PAD9 : ch = CTRL('U'); break; | |
| 1370 #endif | |
| 1371 #ifdef KEY_BACKSPACE /* NCURSES in Keypad mode sends this for Ctrl-H */ | |
| 1372 case KEY_BACKSPACE: ch = CTRL('H'); break; | |
| 1373 #endif | |
| 1374 } | |
| 1375 | |
| 1376 break; | |
| 1377 } | |
| 1378 | |
| 1379 | |
| 1380 if (nodelayf) | |
| 1381 nodelay(win,0); | |
| 1382 | |
| 1383 uindex = -1; | |
| 1384 | |
| 1385 if (!pass_ctrl_keypad && (ch != wch)) | |
| 1386 switch(ch) | |
| 1387 { | |
| 1388 case CTRL('H'): | |
| 1389 case CTRL('L'): | |
| 1390 case CTRL('K'): | |
| 1391 case CTRL('J'): | |
| 1392 case CTRL('Y'): | |
| 1393 case CTRL('U'): | |
| 1394 case CTRL('N'): | |
| 1395 case CTRL('B'): | |
| 1396 return(ch + 0x40); | |
| 1397 } | |
| 1398 | |
| 1399 return(ch & 0x7F); | |
| 1400 } | |
| 1401 | |
| 1402 #if defined(LOADAV) && defined(HAVE_NLIST_H) && defined(HAVE_NLIST) | |
| 1403 /* | |
| 1404 * loadav: | |
| 1405 * Looking up load average in core (for system where the loadav() | |
| 1406 * system call isn't defined | |
| 1407 */ | |
| 1408 | |
| 1409 #include <nlist.h> | |
| 1410 | |
| 1411 struct nlist avenrun = { | |
| 1412 "_avenrun" | |
| 1413 }; | |
| 1414 | |
| 1415 int | |
| 1416 md_loadav(double *avg) | |
| 1417 { | |
| 1418 int kmem; | |
| 1419 | |
| 1420 if ((kmem = open("/dev/kmem", 0)) < 0) | |
| 1421 goto bad; | |
| 1422 nlist(NAMELIST, &avenrun); | |
| 1423 if (avenrun.n_type == 0) | |
| 1424 { | |
| 1425 close(kmem); | |
| 1426 bad: | |
| 1427 avg[0] = 0.0; | |
| 1428 avg[1] = 0.0; | |
| 1429 avg[2] = 0.0; | |
| 1430 return -1; | |
| 1431 } | |
| 1432 | |
| 1433 lseek(kmem, avenrun.n_value, 0); | |
| 1434 read(kmem, (char *) avg, 3 * sizeof (double)); | |
| 1435 close(kmem); | |
| 1436 return 0; | |
| 1437 } | |
| 1438 #else | |
| 1439 int | |
| 1440 md_loadav(double *avg) | |
| 1441 { | |
| 1442 #if defined(HAVE_LOADAV) | |
| 1443 loadav(avg); | |
| 1444 return(0); | |
| 1445 #elif defined(HAVE_GETLOADAVG) | |
| 1446 int ret; | |
| 1447 ret = getloadavg(avg,3); | |
| 1448 return (ret == 3) ? 0 : -1; | |
| 1449 #else | |
| 1450 avg[0] = avg[1] = avg[2] = 0; | |
| 1451 return(-1); | |
| 1452 #endif | |
| 1453 } | |
| 1454 #endif | |
| 1455 | |
| 1456 #ifndef NSIG | |
| 1457 #define NSIG 32 | |
| 1458 #endif | |
| 1459 | |
| 1460 void | |
| 1461 md_ignoreallsignals(void) | |
| 1462 { | |
| 1463 int i; | |
| 1464 | |
| 1465 for (i = 0; i < NSIG; i++) | |
| 1466 signal(i, SIG_IGN); | |
| 1467 } | |
| 1468 | |
| 1469 void | |
| 1470 md_tstphold(void) | |
| 1471 { | |
| 1472 #ifdef SIGTSTP | |
| 1473 /* | |
| 1474 * If a process can be suspended, this code wouldn't work | |
| 1475 */ | |
| 1476 # ifdef SIG_HOLD | |
| 1477 signal(SIGTSTP, SIG_HOLD); | |
| 1478 # else | |
| 1479 signal(SIGTSTP, SIG_IGN); | |
| 1480 # endif | |
| 1481 #endif | |
| 1482 } | |
| 1483 | |
| 1484 void | |
| 1485 md_tstpresume(void (*tstp)(int)) | |
| 1486 { | |
| 1487 #ifdef SIGTSTP | |
| 1488 signal(SIGTSTP, tstp); | |
| 1489 #endif | |
| 1490 } | |
| 1491 | |
| 1492 void | |
| 1493 md_tstpsignal(void) | |
| 1494 { | |
| 1495 #ifdef SIGTSTP | |
| 1496 kill(0, SIGTSTP); /* send actual signal and suspend process */ | |
| 1497 #endif | |
| 1498 } | |
| 1499 | |
| 1500 #if defined(CHECKTIME) | |
| 1501 void | |
| 1502 md_start_checkout_timer(int time) | |
| 1503 { | |
| 1504 int checkout(); | |
| 1505 | |
| 1506 #if defined(HAVE_ALARM) && defined(SIGALRM) | |
| 1507 signal(SIGALRM, checkout); | |
| 1508 alarm(time); | |
| 1509 #endif | |
| 1510 } | |
| 1511 | |
| 1512 void | |
| 1513 md_stop_checkout_timer(void) | |
| 1514 { | |
| 1515 #if defined(SIGALRM) | |
| 1516 signal(SIGALRM, SIG_IGN); | |
| 1517 #endif | |
| 1518 } | |
| 1519 #endif | |
| 1520 | |
| 1521 long | |
| 1522 md_memused() | |
| 1523 { | |
| 1524 #ifdef _WIN32 | |
| 1525 MEMORYSTATUS stat; | |
| 1526 | |
| 1527 GlobalMemoryStatus(&stat); | |
| 1528 | |
| 1529 return((long)stat.dwTotalPageFile); | |
| 1530 #else | |
| 1531 return( (long)sbrk(0) ); | |
| 1532 #endif | |
| 1533 } | |
| 1534 | |
| 1535 int | |
| 1536 md_ucount() | |
| 1537 { | |
| 1538 #if defined(HAVE_UTMPX_H) | |
| 1539 struct utmpx *up=NULL; | |
| 1540 int count=0; | |
| 1541 | |
| 1542 setutxent(); | |
| 1543 do | |
| 1544 { | |
| 1545 up = getutxent(); | |
| 1546 if (up && up->ut_type == USER_PROCESS) | |
| 1547 count++; | |
| 1548 } while(up != NULL); | |
| 1549 | |
| 1550 endutxent(); | |
| 1551 | |
| 1552 return(count); | |
| 1553 #else | |
| 1554 return(1) | |
| 1555 #endif | |
| 1556 } | |
| 1557 | |
| 1558 int | |
| 1559 md_lockfile(FILE *fp) | |
| 1560 { | |
| 1561 int fd; | |
| 1562 int ret; | |
| 1563 | |
| 1564 fflush(fp); | |
| 1565 rewind(fp); | |
| 1566 | |
| 1567 #ifdef _WIN32 | |
| 1568 fd = _fileno(fp); | |
| 1569 ret = _locking(fd,_LK_LOCK,1); | |
| 1570 #else | |
| 1571 fd = fileno(fp); | |
| 1572 | |
| 1573 while((ret = lockf(fd, F_LOCK, 1)) == -1) | |
| 1574 if (errno != EINTR) | |
| 1575 break; | |
| 1576 #endif | |
| 1577 | |
| 1578 return ret; | |
| 1579 } | |
| 1580 | |
| 1581 int | |
| 1582 md_unlockfile(FILE *fp) | |
| 1583 { | |
| 1584 int fd; | |
| 1585 int ret; | |
| 1586 | |
| 1587 fflush(fp); | |
| 1588 rewind(fp); | |
| 1589 | |
| 1590 | |
| 1591 #ifdef _WIN32 | |
| 1592 fd = _fileno(fp); | |
| 1593 ret = _locking(fd,_LK_UNLCK,1); | |
| 1594 #else | |
| 1595 fd = fileno(fp); | |
| 1596 | |
| 1597 while( (ret = lockf(fd, F_ULOCK, 1)) == -1) | |
| 1598 if (errno != EINTR) | |
| 1599 break; | |
| 1600 #endif | |
| 1601 | |
| 1602 return ret; | |
| 1603 } |
