1 1.18 mrg /* $NetBSD: hack.unix.c,v 1.18 2019/02/03 10:48:46 mrg Exp $ */ 2 1.5 christos 3 1.2 mycroft /* 4 1.9 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 1.9 jsm * Amsterdam 6 1.9 jsm * All rights reserved. 7 1.9 jsm * 8 1.9 jsm * Redistribution and use in source and binary forms, with or without 9 1.9 jsm * modification, are permitted provided that the following conditions are 10 1.9 jsm * met: 11 1.9 jsm * 12 1.9 jsm * - Redistributions of source code must retain the above copyright notice, 13 1.9 jsm * this list of conditions and the following disclaimer. 14 1.9 jsm * 15 1.9 jsm * - Redistributions in binary form must reproduce the above copyright 16 1.9 jsm * notice, this list of conditions and the following disclaimer in the 17 1.9 jsm * documentation and/or other materials provided with the distribution. 18 1.9 jsm * 19 1.9 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en 20 1.9 jsm * Informatica, nor the names of its contributors may be used to endorse or 21 1.9 jsm * promote products derived from this software without specific prior 22 1.9 jsm * written permission. 23 1.9 jsm * 24 1.9 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 1.9 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 1.9 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 1.9 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 1.9 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 1.9 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 1.9 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 1.9 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 1.9 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 1.9 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 1.9 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 1.9 jsm */ 36 1.9 jsm 37 1.9 jsm /* 38 1.9 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org> 39 1.9 jsm * All rights reserved. 40 1.9 jsm * 41 1.9 jsm * Redistribution and use in source and binary forms, with or without 42 1.9 jsm * modification, are permitted provided that the following conditions 43 1.9 jsm * are met: 44 1.9 jsm * 1. Redistributions of source code must retain the above copyright 45 1.9 jsm * notice, this list of conditions and the following disclaimer. 46 1.9 jsm * 2. Redistributions in binary form must reproduce the above copyright 47 1.9 jsm * notice, this list of conditions and the following disclaimer in the 48 1.9 jsm * documentation and/or other materials provided with the distribution. 49 1.9 jsm * 3. The name of the author may not be used to endorse or promote products 50 1.9 jsm * derived from this software without specific prior written permission. 51 1.9 jsm * 52 1.9 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 1.9 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 1.9 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 1.9 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 1.9 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 1.9 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 1.9 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 1.9 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 1.9 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 1.9 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.2 mycroft */ 63 1.2 mycroft 64 1.5 christos #include <sys/cdefs.h> 65 1.2 mycroft #ifndef lint 66 1.18 mrg __RCSID("$NetBSD: hack.unix.c,v 1.18 2019/02/03 10:48:46 mrg Exp $"); 67 1.5 christos #endif /* not lint */ 68 1.1 cgd 69 1.1 cgd /* This file collects some Unix dependencies; hack.pager.c contains some more */ 70 1.1 cgd 71 1.1 cgd /* 72 1.1 cgd * The time is used for: 73 1.1 cgd * - seed for random() 74 1.1 cgd * - year on tombstone and yymmdd in record file 75 1.1 cgd * - phase of the moon (various monsters react to NEW_MOON or FULL_MOON) 76 1.1 cgd * - night and midnight (the undead are dangerous at midnight) 77 1.1 cgd * - determination of what files are "very old" 78 1.1 cgd */ 79 1.1 cgd 80 1.1 cgd #include <errno.h> 81 1.5 christos #include <sys/types.h> /* for time_t and stat */ 82 1.5 christos #include <sys/stat.h> 83 1.1 cgd #ifdef BSD 84 1.5 christos #include <sys/time.h> 85 1.1 cgd #else 86 1.5 christos #include <time.h> 87 1.5 christos #endif /* BSD */ 88 1.5 christos #include <stdlib.h> 89 1.5 christos #include <unistd.h> 90 1.5 christos #include <signal.h> 91 1.5 christos #include <fcntl.h> 92 1.1 cgd 93 1.5 christos #include "hack.h" /* mainly for strchr() which depends on BSD */ 94 1.5 christos #include "extern.h" 95 1.1 cgd 96 1.7 christos extern int locknum; 97 1.7 christos 98 1.14 dholland static struct tm *getlt(void); 99 1.14 dholland static int veryold(int); 100 1.14 dholland 101 1.5 christos 102 1.5 christos void 103 1.11 dholland setrandom(void) 104 1.1 cgd { 105 1.5 christos (void) srandom((int) time((time_t *) 0)); 106 1.1 cgd } 107 1.1 cgd 108 1.14 dholland static struct tm * 109 1.11 dholland getlt(void) 110 1.1 cgd { 111 1.5 christos time_t date; 112 1.1 cgd 113 1.1 cgd (void) time(&date); 114 1.5 christos return (localtime(&date)); 115 1.1 cgd } 116 1.1 cgd 117 1.5 christos int 118 1.11 dholland getyear(void) 119 1.1 cgd { 120 1.5 christos return (1900 + getlt()->tm_year); 121 1.1 cgd } 122 1.1 cgd 123 1.5 christos char * 124 1.11 dholland getdatestr(void) 125 1.1 cgd { 126 1.18 mrg static char datestr[32]; 127 1.5 christos struct tm *lt = getlt(); 128 1.1 cgd 129 1.12 dholland (void) snprintf(datestr, sizeof(datestr), "%02d%02d%02d", 130 1.6 kristerw lt->tm_year % 100, lt->tm_mon + 1, lt->tm_mday); 131 1.5 christos return (datestr); 132 1.1 cgd } 133 1.1 cgd 134 1.5 christos int 135 1.11 dholland phase_of_the_moon(void) 136 1.5 christos { /* 0-7, with 0: new, 4: full *//* moon 137 1.5 christos * period: 29.5306 days */ 138 1.5 christos /* year: 365.2422 days */ 139 1.5 christos struct tm *lt = getlt(); 140 1.5 christos int epact, diy, golden; 141 1.1 cgd 142 1.1 cgd diy = lt->tm_yday; 143 1.1 cgd golden = (lt->tm_year % 19) + 1; 144 1.1 cgd epact = (11 * golden + 18) % 30; 145 1.1 cgd if ((epact == 25 && golden > 11) || epact == 24) 146 1.1 cgd epact++; 147 1.1 cgd 148 1.5 christos return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7); 149 1.1 cgd } 150 1.1 cgd 151 1.5 christos int 152 1.11 dholland night(void) 153 1.1 cgd { 154 1.5 christos int hour = getlt()->tm_hour; 155 1.1 cgd 156 1.5 christos return (hour < 6 || hour > 21); 157 1.1 cgd } 158 1.1 cgd 159 1.5 christos int 160 1.11 dholland midnight(void) 161 1.1 cgd { 162 1.5 christos return (getlt()->tm_hour == 0); 163 1.1 cgd } 164 1.1 cgd 165 1.14 dholland static struct stat buf, hbuf; 166 1.5 christos 167 1.5 christos void 168 1.11 dholland gethdate(char *name) 169 1.5 christos { 170 1.5 christos #if 0 171 1.5 christos /* old version - for people short of space */ 172 1.5 christos 173 1.5 christos char *np; 174 1.1 cgd 175 1.5 christos if(stat(name, &hbuf)) 176 1.5 christos error("Cannot get status of %s.", 177 1.5 christos (np = strrchr(name, '/')) ? np+1 : name); 178 1.5 christos #else 179 1.5 christos /* version using PATH from: seismo!gregc (at) ucsf-cgl.ARPA (Greg Couch) */ 180 1.1 cgd 181 1.1 cgd 182 1.5 christos /* 183 1.5 christos * The problem with #include <sys/param.h> is that this include file 184 1.5 christos * does not exist on all systems, and moreover, that it sometimes includes 185 1.5 christos * <sys/types.h> again, so that the compiler sees these typedefs twice. 186 1.5 christos */ 187 1.1 cgd #define MAXPATHLEN 1024 188 1.1 cgd 189 1.8 jsm const char *np, *path; 190 1.5 christos char filename[MAXPATHLEN + 1]; 191 1.5 christos if (strchr(name, '/') != NULL || (path = getenv("PATH")) == NULL) 192 1.1 cgd path = ""; 193 1.1 cgd 194 1.1 cgd for (;;) { 195 1.5 christos if ((np = strchr(path, ':')) == NULL) 196 1.1 cgd np = path + strlen(path); /* point to end str */ 197 1.5 christos if (np - path <= 1) /* %% */ 198 1.13 dholland (void) strlcpy(filename, name, sizeof(filename)); 199 1.1 cgd else { 200 1.13 dholland (void) snprintf(filename, sizeof(filename), 201 1.13 dholland "%.*s/%s", 202 1.13 dholland (int)(np - path), path, name); 203 1.1 cgd } 204 1.1 cgd if (stat(filename, &hbuf) == 0) 205 1.1 cgd return; 206 1.1 cgd if (*np == '\0') 207 1.1 cgd break; 208 1.1 cgd path = np + 1; 209 1.1 cgd } 210 1.1 cgd error("Cannot get status of %s.", 211 1.5 christos (np = strrchr(name, '/')) ? np + 1 : name); 212 1.5 christos #endif 213 1.1 cgd } 214 1.1 cgd 215 1.5 christos int 216 1.8 jsm uptodate(int fd) 217 1.5 christos { 218 1.5 christos if (fstat(fd, &buf)) { 219 1.1 cgd pline("Cannot get status of saved level? "); 220 1.5 christos return (0); 221 1.1 cgd } 222 1.5 christos if (buf.st_mtime < hbuf.st_mtime) { 223 1.1 cgd pline("Saved level is out of date. "); 224 1.5 christos return (0); 225 1.1 cgd } 226 1.5 christos return (1); 227 1.1 cgd } 228 1.1 cgd 229 1.1 cgd /* see whether we should throw away this xlock file */ 230 1.14 dholland static int 231 1.11 dholland veryold(int fd) 232 1.5 christos { 233 1.5 christos int i; 234 1.5 christos time_t date; 235 1.1 cgd 236 1.5 christos if (fstat(fd, &buf)) 237 1.5 christos return (0); /* cannot get status */ 238 1.5 christos if (buf.st_size != sizeof(int)) 239 1.5 christos return (0); /* not an xlock file */ 240 1.1 cgd (void) time(&date); 241 1.5 christos if (date - buf.st_mtime < 3L * 24L * 60L * 60L) { /* recent */ 242 1.5 christos int lockedpid; /* should be the same size as 243 1.5 christos * hackpid */ 244 1.1 cgd 245 1.15 dholland if (read(fd, &lockedpid, sizeof(lockedpid)) != 246 1.5 christos sizeof(lockedpid)) 247 1.1 cgd /* strange ... */ 248 1.5 christos return (0); 249 1.1 cgd 250 1.5 christos /* 251 1.5 christos * From: Rick Adams <seismo!rick> This will work on 252 1.5 christos * 4.1cbsd, 4.2bsd and system 3? & 5. It will do nothing 253 1.5 christos * on V7 or 4.1bsd. 254 1.5 christos */ 255 1.5 christos if (!(kill(lockedpid, 0) == -1 && errno == ESRCH)) 256 1.5 christos return (0); 257 1.1 cgd } 258 1.1 cgd (void) close(fd); 259 1.5 christos for (i = 1; i <= MAXLEVEL; i++) { /* try to remove all */ 260 1.1 cgd glo(i); 261 1.1 cgd (void) unlink(lock); 262 1.1 cgd } 263 1.1 cgd glo(0); 264 1.5 christos if (unlink(lock)) 265 1.5 christos return (0); /* cannot remove it */ 266 1.5 christos return (1); /* success! */ 267 1.1 cgd } 268 1.1 cgd 269 1.5 christos void 270 1.11 dholland getlock(void) 271 1.1 cgd { 272 1.5 christos int i = 0, fd; 273 1.1 cgd 274 1.1 cgd (void) fflush(stdout); 275 1.1 cgd 276 1.1 cgd /* we ignore QUIT and INT at this point */ 277 1.1 cgd if (link(HLOCK, LLOCK) == -1) { 278 1.5 christos int errnosv = errno; 279 1.1 cgd 280 1.1 cgd perror(HLOCK); 281 1.1 cgd printf("Cannot link %s to %s\n", LLOCK, HLOCK); 282 1.5 christos switch (errnosv) { 283 1.1 cgd case ENOENT: 284 1.5 christos printf("Perhaps there is no (empty) file %s ?\n", HLOCK); 285 1.5 christos break; 286 1.1 cgd case EACCES: 287 1.5 christos printf("It seems you don't have write permission here.\n"); 288 1.5 christos break; 289 1.1 cgd case EEXIST: 290 1.5 christos printf("(Try again or rm %s.)\n", LLOCK); 291 1.5 christos break; 292 1.1 cgd default: 293 1.5 christos printf("I don't know what is wrong."); 294 1.1 cgd } 295 1.1 cgd getret(); 296 1.5 christos error("%s", ""); 297 1.5 christos /* NOTREACHED */ 298 1.1 cgd } 299 1.1 cgd regularize(lock); 300 1.1 cgd glo(0); 301 1.5 christos if (locknum > 25) 302 1.5 christos locknum = 25; 303 1.1 cgd 304 1.1 cgd do { 305 1.5 christos if (locknum) 306 1.5 christos lock[0] = 'a' + i++; 307 1.1 cgd 308 1.8 jsm if ((fd = open(lock, O_RDONLY)) == -1) { 309 1.5 christos if (errno == ENOENT) 310 1.5 christos goto gotlock; /* no such file */ 311 1.1 cgd perror(lock); 312 1.1 cgd (void) unlink(LLOCK); 313 1.1 cgd error("Cannot open %s", lock); 314 1.1 cgd } 315 1.5 christos if (veryold(fd))/* if true, this closes fd and unlinks lock */ 316 1.1 cgd goto gotlock; 317 1.1 cgd (void) close(fd); 318 1.5 christos } while (i < locknum); 319 1.1 cgd 320 1.1 cgd (void) unlink(LLOCK); 321 1.1 cgd error(locknum ? "Too many hacks running now." 322 1.5 christos : "There is a game in progress under your name."); 323 1.1 cgd gotlock: 324 1.1 cgd fd = creat(lock, FMASK); 325 1.5 christos if (unlink(LLOCK) == -1) 326 1.1 cgd error("Cannot unlink %s.", LLOCK); 327 1.5 christos if (fd == -1) { 328 1.1 cgd error("cannot creat lock file."); 329 1.1 cgd } else { 330 1.15 dholland if (write(fd, &hackpid, sizeof(hackpid)) 331 1.5 christos != sizeof(hackpid)) { 332 1.1 cgd error("cannot write lock"); 333 1.1 cgd } 334 1.5 christos if (close(fd) == -1) { 335 1.1 cgd error("cannot close lock"); 336 1.1 cgd } 337 1.1 cgd } 338 1.5 christos } 339 1.1 cgd 340 1.1 cgd #ifdef MAIL 341 1.1 cgd 342 1.1 cgd /* 343 1.1 cgd * Notify user when new mail has arrived. [Idea from Merlyn Leroy, but 344 1.1 cgd * I don't know the details of his implementation.] 345 1.1 cgd * { Later note: he disliked my calling a general mailreader and felt that 346 1.1 cgd * hack should do the paging itself. But when I get mail, I want to put it 347 1.1 cgd * in some folder, reply, etc. - it would be unreasonable to put all these 348 1.1 cgd * functions in hack. } 349 1.1 cgd * The mail daemon '2' is at present not a real monster, but only a visual 350 1.1 cgd * effect. Thus, makemon() is superfluous. This might become otherwise, 351 1.1 cgd * however. The motion of '2' is less restrained than usual: diagonal moves 352 1.1 cgd * from a DOOR are possible. He might also use SDOOR's. Also, '2' is visible 353 1.1 cgd * in a ROOM, even when you are Blind. 354 1.1 cgd * Its path should be longer when you are Telepat-hic and Blind. 355 1.1 cgd * 356 1.1 cgd * Interesting side effects: 357 1.1 cgd * - You can get rich by sending yourself a lot of mail and selling 358 1.1 cgd * it to the shopkeeper. Unfortunately mail isn't very valuable. 359 1.1 cgd * - You might die in case '2' comes along at a critical moment during 360 1.1 cgd * a fight and delivers a scroll the weight of which causes you to 361 1.1 cgd * collapse. 362 1.1 cgd * 363 1.1 cgd * Possible extensions: 364 1.1 cgd * - Open the file MAIL and do fstat instead of stat for efficiency. 365 1.1 cgd * (But sh uses stat, so this cannot be too bad.) 366 1.1 cgd * - Examine the mail and produce a scroll of mail called "From somebody". 367 1.1 cgd * - Invoke MAILREADER in such a way that only this single letter is read. 368 1.1 cgd * 369 1.1 cgd * - Make him lose his mail when a Nymph steals the letter. 370 1.1 cgd * - Do something to the text when the scroll is enchanted or cancelled. 371 1.1 cgd */ 372 1.1 cgd #include "def.mkroom.h" 373 1.5 christos static struct stat omstat, nmstat; 374 1.5 christos static char *mailbox; 375 1.5 christos static long laststattime; 376 1.1 cgd 377 1.5 christos void 378 1.11 dholland getmailstatus(void) 379 1.5 christos { 380 1.5 christos if (!(mailbox = getenv("MAIL"))) 381 1.1 cgd return; 382 1.5 christos if (stat(mailbox, &omstat)) { 383 1.1 cgd #ifdef PERMANENT_MAILBOX 384 1.1 cgd pline("Cannot get status of MAIL=%s .", mailbox); 385 1.1 cgd mailbox = 0; 386 1.1 cgd #else 387 1.1 cgd omstat.st_mtime = 0; 388 1.5 christos #endif /* PERMANENT_MAILBOX */ 389 1.1 cgd } 390 1.1 cgd } 391 1.1 cgd 392 1.5 christos void 393 1.11 dholland ckmailstatus(void) 394 1.5 christos { 395 1.5 christos if (!mailbox 396 1.1 cgd #ifdef MAILCKFREQ 397 1.5 christos || moves < laststattime + MAILCKFREQ 398 1.5 christos #endif /* MAILCKFREQ */ 399 1.5 christos ) 400 1.1 cgd return; 401 1.1 cgd laststattime = moves; 402 1.5 christos if (stat(mailbox, &nmstat)) { 403 1.1 cgd #ifdef PERMANENT_MAILBOX 404 1.1 cgd pline("Cannot get status of MAIL=%s anymore.", mailbox); 405 1.1 cgd mailbox = 0; 406 1.1 cgd #else 407 1.1 cgd nmstat.st_mtime = 0; 408 1.5 christos #endif /* PERMANENT_MAILBOX */ 409 1.5 christos } else if (nmstat.st_mtime > omstat.st_mtime) { 410 1.5 christos if (nmstat.st_size) 411 1.1 cgd newmail(); 412 1.5 christos getmailstatus();/* might be too late ... */ 413 1.1 cgd } 414 1.1 cgd } 415 1.1 cgd 416 1.5 christos void 417 1.11 dholland newmail(void) 418 1.5 christos { 419 1.1 cgd /* produce a scroll of mail */ 420 1.5 christos struct obj *obj; 421 1.5 christos struct monst *md; 422 1.1 cgd 423 1.1 cgd obj = mksobj(SCR_MAIL); 424 1.5 christos if (md = makemon(&pm_mail_daemon, u.ux, u.uy)) /* always succeeds */ 425 1.5 christos mdrush(md, 0); 426 1.1 cgd 427 1.1 cgd pline("\"Hello, %s! I have some mail for you.\"", plname); 428 1.5 christos if (md) { 429 1.5 christos if (dist(md->mx, md->my) > 2) 430 1.1 cgd pline("\"Catch!\""); 431 1.1 cgd more(); 432 1.1 cgd 433 1.1 cgd /* let him disappear again */ 434 1.5 christos mdrush(md, 1); 435 1.1 cgd mondead(md); 436 1.1 cgd } 437 1.1 cgd obj = addinv(obj); 438 1.5 christos (void) identify(obj); /* set known and do prinv() */ 439 1.1 cgd } 440 1.1 cgd 441 1.1 cgd /* make md run through the cave */ 442 1.5 christos void 443 1.11 dholland mdrush(struct monst *md, boolean away) 444 1.5 christos { 445 1.5 christos int uroom = inroom(u.ux, u.uy); 446 1.5 christos if (uroom >= 0) { 447 1.5 christos int tmp = rooms[uroom].fdoor; 448 1.5 christos int cnt = rooms[uroom].doorct; 449 1.5 christos int fx = u.ux, fy = u.uy; 450 1.5 christos while (cnt--) { 451 1.5 christos if (dist(fx, fy) < dist(doors[tmp].x, doors[tmp].y)) { 452 1.1 cgd fx = doors[tmp].x; 453 1.1 cgd fy = doors[tmp].y; 454 1.1 cgd } 455 1.1 cgd tmp++; 456 1.1 cgd } 457 1.1 cgd tmp_at(-1, md->data->mlet); /* open call */ 458 1.5 christos if (away) { /* interchange origin and destination */ 459 1.1 cgd unpmon(md); 460 1.5 christos tmp = fx; 461 1.5 christos fx = md->mx; 462 1.5 christos md->mx = tmp; 463 1.5 christos tmp = fy; 464 1.5 christos fy = md->my; 465 1.5 christos md->my = tmp; 466 1.1 cgd } 467 1.5 christos while (fx != md->mx || fy != md->my) { 468 1.5 christos int dx, dy, nfx = fx, nfy = fy, d1, 469 1.5 christos d2; 470 1.5 christos 471 1.5 christos tmp_at(fx, fy); 472 1.5 christos d1 = DIST(fx, fy, md->mx, md->my); 473 1.5 christos for (dx = -1; dx <= 1; dx++) 474 1.5 christos for (dy = -1; dy <= 1; dy++) 475 1.5 christos if (dx || dy) { 476 1.5 christos d2 = DIST(fx + dx, fy + dy, md->mx, md->my); 477 1.5 christos if (d2 < d1) { 478 1.5 christos d1 = d2; 479 1.5 christos nfx = fx + dx; 480 1.5 christos nfy = fy + dy; 481 1.5 christos } 482 1.5 christos } 483 1.5 christos if (nfx != fx || nfy != fy) { 484 1.5 christos fx = nfx; 485 1.5 christos fy = nfy; 486 1.5 christos } else { 487 1.5 christos if (!away) { 488 1.5 christos md->mx = fx; 489 1.5 christos md->my = fy; 490 1.1 cgd } 491 1.5 christos break; 492 1.5 christos } 493 1.1 cgd } 494 1.5 christos tmp_at(-1, -1); /* close call */ 495 1.1 cgd } 496 1.5 christos if (!away) 497 1.1 cgd pmon(md); 498 1.1 cgd } 499 1.1 cgd 500 1.5 christos void 501 1.11 dholland readmail(void) 502 1.5 christos { 503 1.5 christos #ifdef DEF_MAILREADER /* This implies that UNIX is defined */ 504 1.5 christos char *mr = 0; 505 1.1 cgd more(); 506 1.5 christos if (!(mr = getenv("MAILREADER"))) 507 1.1 cgd mr = DEF_MAILREADER; 508 1.5 christos if (child(1)) { 509 1.17 plunky execl(mr, mr, (char *)NULL); 510 1.1 cgd exit(1); 511 1.1 cgd } 512 1.5 christos #else /* DEF_MAILREADER */ 513 1.1 cgd (void) page_file(mailbox, FALSE); 514 1.5 christos #endif /* DEF_MAILREADER */ 515 1.5 christos /* 516 1.5 christos * get new stat; not entirely correct: there is a small time window 517 1.5 christos * where we do not see new mail 518 1.5 christos */ 519 1.1 cgd getmailstatus(); 520 1.1 cgd } 521 1.5 christos #endif /* MAIL */ 522 1.1 cgd 523 1.11 dholland /* 524 1.11 dholland * normalize file name - we don't like ..'s or /'s 525 1.11 dholland */ 526 1.5 christos void 527 1.11 dholland regularize(char *s) 528 1.1 cgd { 529 1.5 christos char *lp; 530 1.1 cgd 531 1.5 christos while ((lp = strchr(s, '.')) || (lp = strchr(s, '/'))) 532 1.1 cgd *lp = '_'; 533 1.1 cgd } 534