Print this page
5088 it's probably ok for vi to stop working around pdp-11 bugs now
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/vi/port/ex.c
+++ new/usr/src/cmd/vi/port/ex.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 29 /* Copyright (c) 1981 Regents of the University of California */
30 30
31 -#pragma ident "%Z%%M% %I% %E% SMI"
32 -
33 31 #include "ex.h"
34 32 #include "ex_argv.h"
35 33 #include "ex_temp.h"
36 34 #include "ex_tty.h"
37 35 #include <stdlib.h>
38 36 #include <locale.h>
39 37 #include <stdio.h>
40 38 #ifdef TRACE
41 39 unsigned char tttrace[BUFSIZ];
42 40 #endif
43 41
44 42 #define EQ(a, b) (strcmp(a, b) == 0)
45 43
46 44 char *strrchr();
47 45 void init_re(void);
48 46
49 47 /*
50 48 * The code for ex is divided as follows:
51 49 *
52 50 * ex.c Entry point and routines handling interrupt, hangup
53 51 * signals; initialization code.
54 52 *
55 53 * ex_addr.c Address parsing routines for command mode decoding.
56 54 * Routines to set and check address ranges on commands.
57 55 *
58 56 * ex_cmds.c Command mode command decoding.
59 57 *
60 58 * ex_cmds2.c Subroutines for command decoding and processing of
61 59 * file names in the argument list. Routines to print
62 60 * messages and reset state when errors occur.
63 61 *
64 62 * ex_cmdsub.c Subroutines which implement command mode functions
65 63 * such as append, delete, join.
66 64 *
67 65 * ex_data.c Initialization of options.
68 66 *
69 67 * ex_get.c Command mode input routines.
70 68 *
71 69 * ex_io.c General input/output processing: file i/o, unix
72 70 * escapes, filtering, source commands, preserving
73 71 * and recovering.
74 72 *
75 73 * ex_put.c Terminal driving and optimizing routines for low-level
76 74 * output (cursor-positioning); output line formatting
77 75 * routines.
78 76 *
79 77 * ex_re.c Global commands, substitute, regular expression
80 78 * compilation and execution.
81 79 *
82 80 * ex_set.c The set command.
83 81 *
84 82 * ex_subr.c Loads of miscellaneous subroutines.
85 83 *
86 84 * ex_temp.c Editor buffer routines for main buffer and also
87 85 * for named buffers (Q registers if you will.)
88 86 *
89 87 * ex_tty.c Terminal dependent initializations from termcap
90 88 * data base, grabbing of tty modes (at beginning
91 89 * and after escapes).
92 90 *
93 91 * ex_unix.c Routines for the ! command and its variations.
94 92 *
95 93 * ex_v*.c Visual/open mode routines... see ex_v.c for a
96 94 * guide to the overall organization.
97 95 */
98 96
99 97 /*
100 98 * This sets the Version of ex/vi for both the exstrings file and
101 99 * the version command (":ver").
102 100 */
103 101
104 102 /* variable used by ":ver" command */
105 103 unsigned char *Version = (unsigned char *)"Version SVR4.0, Solaris 2.5.0";
106 104
107 105 /*
108 106 * NOTE: when changing the Version number, it must be changed in the
109 107 * following files:
110 108 *
111 109 * port/READ_ME
112 110 * port/ex.c
113 111 * port/ex.news
114 112 *
115 113 */
116 114 #ifdef XPG4
117 115 unsigned char *savepat = (unsigned char *) NULL; /* firstpat storage */
118 116 #endif /* XPG4 */
119 117
120 118 /*
121 119 * Main procedure. Process arguments and then
122 120 * transfer control to the main command processing loop
123 121 * in the routine commands. We are entered as either "ex", "edit", "vi"
124 122 * or "view" and the distinction is made here. For edit we just diddle options;
125 123 * for vi we actually force an early visual command.
126 124 */
127 125 static unsigned char cryptkey[19]; /* contents of encryption key */
128 126
129 127 static void usage(unsigned char *);
130 128
131 129 static int validate_exrc(unsigned char *);
132 130
133 131 void init(void);
134 132
135 133 int
136 134 main(int ac, char *av[])
137 135 {
138 136 extern char *optarg;
139 137 extern int optind;
140 138 unsigned char *rcvname = 0;
141 139 unsigned char *cp;
142 140 int c;
143 141 unsigned char *cmdnam;
144 142 bool recov = 0;
145 143 bool ivis = 0;
146 144 bool itag = 0;
147 145 bool fast = 0;
148 146 extern int verbose;
149 147 int argcounter = 0;
150 148 extern int tags_flag; /* Set if tag file is not sorted (-S flag) */
151 149 unsigned char scratch [PATH_MAX+1]; /* temp for sourcing rc file(s) */
152 150 int vret = 0;
153 151 unsigned char exrcpath [PATH_MAX+1]; /* temp for sourcing rc file(s) */
154 152 int toptseen = 0;
155 153 #ifdef TRACE
156 154 unsigned char *tracef;
157 155 #endif
158 156 tagflg = 0;
159 157 (void) setlocale(LC_ALL, "");
160 158 #if !defined(TEXT_DOMAIN)
161 159 #define TEXT_DOMAIN "SYS_TEST"
162 160 #endif
163 161 (void) textdomain(TEXT_DOMAIN);
164 162
165 163 /*
166 164 * Immediately grab the tty modes so that we won't
167 165 * get messed up if an interrupt comes in quickly.
168 166 */
169 167 (void) gTTY(2);
170 168 normf = tty;
171 169 ppid = getpid();
172 170 /* Note - this will core dump if you didn't -DSINGLE in CFLAGS */
173 171 lines = 24;
174 172 columns = 80; /* until defined right by setupterm */
175 173 /*
176 174 * Defend against d's, v's, w's, and a's in directories of
177 175 * path leading to our true name.
178 176 */
179 177 if ((cmdnam = (unsigned char *)strrchr(av[0], '/')) != 0)
180 178 cmdnam++;
181 179 else
182 180 cmdnam = (unsigned char *)av[0];
183 181
184 182 if (EQ((char *)cmdnam, "vi"))
185 183 ivis = 1;
186 184 else if (EQ(cmdnam, "view")) {
187 185 ivis = 1;
188 186 value(vi_READONLY) = 1;
189 187 } else if (EQ(cmdnam, "vedit")) {
190 188 ivis = 1;
191 189 value(vi_NOVICE) = 1;
192 190 value(vi_REPORT) = 1;
193 191 value(vi_MAGIC) = 0;
194 192 value(vi_SHOWMODE) = 1;
195 193 } else if (EQ(cmdnam, "edit")) {
196 194 value(vi_NOVICE) = 1;
197 195 value(vi_REPORT) = 1;
198 196 value(vi_MAGIC) = 0;
199 197 value(vi_SHOWMODE) = 1;
200 198 }
201 199
202 200 #ifdef XPG4
203 201 {
204 202 struct winsize jwin;
205 203 char *envptr;
206 204
207 205 envlines = envcolumns = -1;
208 206 oldlines = oldcolumns = -1;
209 207
210 208 if (ioctl(0, TIOCGWINSZ, &jwin) != -1) {
211 209 oldlines = jwin.ws_row;
212 210 oldcolumns = jwin.ws_col;
213 211 }
214 212
215 213 if ((envptr = getenv("LINES")) != NULL &&
216 214 *envptr != '\0' && isdigit(*envptr)) {
217 215 if ((envlines = atoi(envptr)) <= 0) {
218 216 envlines = -1;
219 217 }
220 218 }
221 219
222 220 if ((envptr = getenv("COLUMNS")) != NULL &&
223 221 *envptr != '\0' && isdigit(*envptr)) {
224 222 if ((envcolumns = atoi(envptr)) <= 0) {
225 223 envcolumns = -1;
226 224 }
227 225 }
228 226 }
229 227 #endif /* XPG4 */
230 228
231 229 draino();
232 230 pstop();
233 231
↓ open down ↓ |
191 lines elided |
↑ open up ↑ |
234 232 /*
235 233 * Initialize interrupt handling.
236 234 */
237 235 oldhup = signal(SIGHUP, SIG_IGN);
238 236 if (oldhup == SIG_DFL)
239 237 signal(SIGHUP, onhup);
240 238 oldquit = signal(SIGQUIT, SIG_IGN);
241 239 ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
242 240 if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
243 241 signal(SIGTERM, onhup);
244 - if (signal(SIGEMT, SIG_IGN) == SIG_DFL)
245 - signal(SIGEMT, onemt);
246 242 signal(SIGILL, oncore);
247 243 signal(SIGTRAP, oncore);
248 244 signal(SIGIOT, oncore);
249 245 signal(SIGFPE, oncore);
250 246 signal(SIGBUS, oncore);
251 247 signal(SIGSEGV, oncore);
252 248 signal(SIGPIPE, oncore);
253 249 init_re();
254 250 while (1) {
255 251 #ifdef TRACE
256 252 while ((c = getopt(ac, (char **)av, "VU:Lc:Tvt:rlw:xRCsS")) !=
257 253 EOF)
258 254 #else
259 255 while ((c = getopt(ac, (char **)av,
260 256 "VLc:vt:rlw:xRCsS")) != EOF)
261 257 #endif
262 258 switch (c) {
263 259 case 's':
264 260 hush = 1;
265 261 value(vi_AUTOPRINT) = 0;
266 262 fast++;
267 263 break;
268 264
269 265 case 'R':
270 266 value(vi_READONLY) = 1;
271 267 break;
272 268 case 'S':
273 269 tags_flag = 1;
274 270 break;
275 271 #ifdef TRACE
276 272 case 'T':
277 273 tracef = (unsigned char *)"trace";
278 274 goto trace;
279 275
280 276 case 'U':
281 277 tracef = tttrace;
282 278 strcpy(tracef, optarg);
283 279 trace:
284 280 trace = fopen((char *)tracef, "w");
285 281 #define tracbuf NULL
286 282 if (trace == NULL)
287 283 viprintf("Trace create error\n");
288 284 else
289 285 setbuf(trace, (char *)tracbuf);
290 286 break;
291 287 #endif
292 288 case 'c':
293 289 if (optarg != NULL)
294 290 firstpat = (unsigned char *)optarg;
295 291 else
296 292 firstpat = (unsigned char *)"";
297 293 break;
298 294
299 295 case 'l':
300 296 value(vi_LISP) = 1;
301 297 value(vi_SHOWMATCH) = 1;
302 298 break;
303 299
304 300 case 'r':
305 301 if (av[optind] && (c = av[optind][0]) &&
306 302 c != '-') {
307 303 if ((strlen(av[optind])) >=
308 304 sizeof (savedfile)) {
309 305 (void) fprintf(stderr, gettext(
310 306 "Recovered file name"
311 307 " too long\n"));
312 308 exit(1);
313 309 }
314 310
315 311 rcvname = (unsigned char *)av[optind];
316 312 optind++;
317 313 }
318 314
319 315 case 'L':
320 316 recov++;
321 317 break;
322 318
323 319 case 'V':
324 320 verbose = 1;
325 321 break;
326 322
327 323 case 't':
328 324 if (toptseen) {
329 325 usage(cmdnam);
330 326 exit(1);
331 327 } else {
332 328 toptseen++;
333 329 }
334 330 itag = tagflg = 1; /* -t option */
335 331 if (strlcpy(lasttag, optarg,
336 332 sizeof (lasttag)) >= sizeof (lasttag)) {
337 333 (void) fprintf(stderr, gettext("Tag"
338 334 " file name too long\n"));
339 335 exit(1);
340 336 }
341 337 break;
342 338
343 339 case 'w':
344 340 defwind = 0;
345 341 if (optarg[0] == NULL)
346 342 defwind = 3;
347 343 else for (cp = (unsigned char *)optarg;
348 344 isdigit(*cp); cp++)
349 345 defwind = 10*defwind + *cp - '0';
350 346 if (defwind < 0)
351 347 defwind = 3;
352 348 break;
353 349
354 350 case 'C':
355 351 crflag = 1;
356 352 xflag = 1;
357 353 break;
358 354
359 355 case 'x':
360 356 /* encrypted mode */
361 357 xflag = 1;
362 358 crflag = -1;
363 359 break;
364 360
365 361 case 'v':
366 362 ivis = 1;
367 363 break;
368 364
369 365 default:
370 366 usage(cmdnam);
371 367 exit(1);
372 368 }
373 369 if (av[optind] && av[optind][0] == '+' &&
374 370 av[optind-1] && strcmp(av[optind-1], "--")) {
375 371 firstpat = (unsigned char *)&av[optind][1];
376 372 optind++;
377 373 continue;
378 374 } else if (av[optind] && av[optind][0] == '-' &&
379 375 av[optind-1] && strcmp(av[optind-1], "--")) {
380 376 hush = 1;
381 377 value(vi_AUTOPRINT) = 0;
382 378 fast++;
383 379 optind++;
384 380 continue;
385 381 }
386 382 break;
387 383 }
388 384
389 385 if (isatty(0) == 0) {
390 386 /*
391 387 * If -V option is set and input is coming in via
392 388 * stdin then vi behavior should be ignored. The vi
393 389 * command should act like ex and only process ex commands
394 390 * and echo the input ex commands to stderr
395 391 */
396 392 if (verbose == 1) {
397 393 ivis = 0;
398 394 }
399 395
400 396 /*
401 397 * If the standard input is not a terminal device,
402 398 * it is as if the -s option has been specified.
403 399 */
404 400 if (ivis == 0) {
405 401 hush = 1;
406 402 value(vi_AUTOPRINT) = 0;
407 403 fast++;
408 404 }
409 405 }
410 406
411 407 ac -= optind;
412 408 av = &av[optind];
413 409
414 410 for (argcounter = 0; argcounter < ac; argcounter++) {
415 411 if ((strlen(av[argcounter])) >= sizeof (savedfile)) {
416 412 (void) fprintf(stderr, gettext("File argument"
417 413 " too long\n"));
418 414 exit(1);
419 415 }
420 416 }
421 417
422 418 #ifdef SIGTSTP
423 419 if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL)
424 420 signal(SIGTSTP, onsusp), dosusp++;
425 421 #endif
426 422
427 423 if (xflag) {
428 424 permflag = 1;
429 425 if ((kflag = run_setkey(perm,
430 426 (key = (unsigned char *)getpass(
431 427 gettext("Enter key:"))))) == -1) {
432 428 kflag = 0;
433 429 xflag = 0;
434 430 smerror(gettext("Encryption facility not available\n"));
435 431 }
436 432 if (kflag == 0)
437 433 crflag = 0;
438 434 else {
439 435 strcpy(cryptkey, "CrYpTkEy=XXXXXXXXX");
440 436 strcpy(cryptkey + 9, key);
441 437 if (putenv((char *)cryptkey) != 0)
442 438 smerror(gettext(" Cannot copy key to environment"));
443 439 }
444 440
445 441 }
446 442 #ifndef PRESUNEUC
447 443 /*
448 444 * Perform locale-specific initialization
449 445 */
450 446 localize();
451 447 #endif /* PRESUNEUC */
452 448
453 449 /*
454 450 * Initialize end of core pointers.
455 451 * Normally we avoid breaking back to fendcore after each
456 452 * file since this can be expensive (much core-core copying).
457 453 * If your system can scatter load processes you could do
458 454 * this as ed does, saving a little core, but it will probably
459 455 * not often make much difference.
460 456 */
461 457 fendcore = (line *) sbrk(0);
462 458 endcore = fendcore - 2;
463 459
464 460 /*
465 461 * If we are doing a recover and no filename
466 462 * was given, then execute an exrecover command with
467 463 * the -r option to type out the list of saved file names.
468 464 * Otherwise set the remembered file name to the first argument
469 465 * file name so the "recover" initial command will find it.
470 466 */
471 467 if (recov) {
472 468 if (ac == 0 && (rcvname == NULL || *rcvname == NULL)) {
473 469 ppid = 0;
474 470 setrupt();
475 471 execlp(EXRECOVER, "exrecover", "-r", (char *)0);
476 472 filioerr(EXRECOVER);
477 473 exit(++errcnt);
478 474 }
479 475 if (rcvname && *rcvname)
480 476 (void) strlcpy(savedfile, rcvname, sizeof (savedfile));
481 477 else {
482 478 (void) strlcpy(savedfile, *av++, sizeof (savedfile));
483 479 ac--;
484 480 }
485 481 }
486 482
487 483 /*
488 484 * Initialize the argument list.
489 485 */
490 486 argv0 = (unsigned char **)av;
491 487 argc0 = ac;
492 488 args0 = (unsigned char *)av[0];
493 489 erewind();
494 490
495 491 /*
496 492 * Initialize a temporary file (buffer) and
497 493 * set up terminal environment. Read user startup commands.
498 494 */
499 495 if (setexit() == 0) {
500 496 setrupt();
501 497 intty = isatty(0);
502 498 value(vi_PROMPT) = intty;
503 499 if (((cp = (unsigned char *)getenv("SHELL")) != NULL) &&
504 500 (*cp != '\0')) {
505 501 if (strlen(cp) < sizeof (shell)) {
506 502 (void) strlcpy(shell, cp, sizeof (shell));
507 503 }
508 504 }
509 505 if (fast)
510 506 setterm((unsigned char *)"dumb");
511 507 else {
512 508 gettmode();
513 509 cp = (unsigned char *)getenv("TERM");
514 510 if (cp == NULL || *cp == '\0')
515 511 cp = (unsigned char *)"unknown";
516 512 setterm(cp);
517 513 }
518 514 }
519 515
520 516 /*
521 517 * Bring up some code from init()
522 518 * This is still done in init later. This
523 519 * avoids null pointer problems
524 520 */
525 521
526 522 dot = zero = truedol = unddol = dol = fendcore;
527 523 one = zero+1;
528 524 {
529 525 int i;
530 526
531 527 for (i = 0; i <= 'z'-'a'+1; i++)
532 528 names[i] = 1;
533 529 }
534 530
535 531 if (setexit() == 0 && !fast) {
536 532 if ((globp =
537 533 (unsigned char *) getenv("EXINIT")) && *globp) {
538 534 if (ivis)
539 535 inexrc = 1;
540 536 commands(1, 1);
541 537 inexrc = 0;
542 538 } else {
543 539 globp = 0;
544 540 if ((cp = (unsigned char *) getenv("HOME")) !=
545 541 0 && *cp) {
546 542 strncpy(scratch, cp, sizeof (scratch) - 1);
547 543 strncat(scratch, "/.exrc",
548 544 sizeof (scratch) - 1 - strlen(scratch));
549 545 if (ivis)
550 546 inexrc = 1;
551 547 if ((vret = validate_exrc(scratch)) == 0) {
552 548 source(scratch, 1);
553 549 } else {
554 550 if (vret == -1) {
555 551 error(gettext(
556 552 "Not owner of .exrc "
557 553 "or .exrc is group or "
558 554 "world writable"));
559 555 }
560 556 }
561 557 inexrc = 0;
562 558 }
563 559 }
564 560
565 561 /*
566 562 * Allow local .exrc if the "exrc" option was set. This
567 563 * loses if . is $HOME, but nobody should notice unless
568 564 * they do stupid things like putting a version command
569 565 * in .exrc.
570 566 * Besides, they should be using EXINIT, not .exrc, right?
571 567 */
572 568
573 569 if (value(vi_EXRC)) {
574 570 if (ivis)
575 571 inexrc = 1;
576 572 if ((cp = (unsigned char *) getenv("PWD")) != 0 &&
577 573 *cp) {
578 574 strncpy(exrcpath, cp, sizeof (exrcpath) - 1);
579 575 strncat(exrcpath, "/.exrc",
580 576 sizeof (exrcpath) - 1 - strlen(exrcpath));
581 577 if (strcmp(scratch, exrcpath) != 0) {
582 578 if ((vret =
583 579 validate_exrc(exrcpath)) == 0) {
584 580 source(exrcpath, 1);
585 581 } else {
586 582 if (vret == -1) {
587 583 error(gettext(
588 584 "Not owner of "
589 585 ".exrc or .exrc "
590 586 "is group or world "
591 587 "writable"));
592 588 }
593 589 }
594 590 }
595 591 }
596 592 inexrc = 0;
597 593 }
598 594 }
599 595
600 596 init(); /* moved after prev 2 chunks to fix directory option */
601 597
602 598 /*
603 599 * Initial processing. Handle tag, recover, and file argument
604 600 * implied next commands. If going in as 'vi', then don't do
605 601 * anything, just set initev so we will do it later (from within
606 602 * visual).
607 603 */
608 604 if (setexit() == 0) {
609 605 if (recov)
610 606 globp = (unsigned char *)"recover";
611 607 else if (itag) {
612 608 globp = ivis ? (unsigned char *)"tag" :
613 609 (unsigned char *)"tag|p";
614 610 #ifdef XPG4
615 611 if (firstpat != NULL) {
616 612 /*
617 613 * if the user specified the -t and -c
618 614 * flags together, then we service these
619 615 * commands here. -t is handled first.
620 616 */
621 617 savepat = firstpat;
622 618 firstpat = NULL;
623 619 inglobal = 1;
624 620 commands(1, 1);
625 621
626 622 /* now handle the -c argument: */
627 623 globp = savepat;
628 624 commands(1, 1);
629 625 inglobal = 0;
630 626 globp = savepat = NULL;
631 627
632 628 /* the above isn't sufficient for ex mode: */
633 629 if (!ivis) {
634 630 setdot();
635 631 nonzero();
636 632 plines(addr1, addr2, 1);
637 633 }
638 634 }
639 635 #endif /* XPG4 */
640 636 } else if (argc)
641 637 globp = (unsigned char *)"next";
642 638 if (ivis)
643 639 initev = globp;
644 640 else if (globp) {
645 641 inglobal = 1;
646 642 commands(1, 1);
647 643 inglobal = 0;
648 644 }
649 645 }
650 646
651 647 /*
652 648 * Vi command... go into visual.
653 649 */
654 650 if (ivis) {
655 651 /*
656 652 * Don't have to be upward compatible
657 653 * by starting editing at line $.
658 654 */
659 655 #ifdef XPG4
660 656 if (!itag && (dol > zero))
661 657 #else /* XPG4 */
662 658 if (dol > zero)
663 659 #endif /* XPG4 */
664 660 dot = one;
665 661 globp = (unsigned char *)"visual";
666 662 if (setexit() == 0)
667 663 commands(1, 1);
668 664 }
669 665
670 666 /*
671 667 * Clear out trash in state accumulated by startup,
672 668 * and then do the main command loop for a normal edit.
673 669 * If you quit out of a 'vi' command by doing Q or ^\,
674 670 * you also fall through to here.
675 671 */
676 672 seenprompt = 1;
677 673 ungetchar(0);
678 674 globp = 0;
679 675 initev = 0;
680 676 setlastchar('\n');
681 677 setexit();
682 678 commands(0, 0);
683 679 cleanup(1);
684 680 return (errcnt);
685 681 }
686 682
687 683 /*
688 684 * Initialization, before editing a new file.
689 685 * Main thing here is to get a new buffer (in fileinit),
690 686 * rest is peripheral state resetting.
691 687 */
692 688 void
693 689 init(void)
694 690 {
695 691 int i;
696 692 void (*pstat)();
697 693 fileinit();
698 694 dot = zero = truedol = unddol = dol = fendcore;
699 695 one = zero+1;
700 696 undkind = UNDNONE;
701 697 chng = 0;
702 698 edited = 0;
703 699 for (i = 0; i <= 'z'-'a'+1; i++)
704 700 names[i] = 1;
705 701 anymarks = 0;
706 702 if (xflag) {
707 703 xtflag = 1;
708 704 /* ignore SIGINT before crypt process */
709 705 pstat = signal(SIGINT, SIG_IGN);
710 706 if (tpermflag)
711 707 (void) crypt_close(tperm);
712 708 tpermflag = 1;
713 709 if (makekey(tperm) != 0) {
714 710 xtflag = 0;
715 711 smerror(gettext(
716 712 "Warning--Cannot encrypt temporary buffer\n"));
717 713 }
718 714 signal(SIGINT, pstat);
719 715 }
720 716 }
721 717
722 718 /*
723 719 * Return last component of unix path name p.
724 720 */
725 721 unsigned char *
726 722 tailpath(p)
727 723 unsigned char *p;
728 724 {
729 725 unsigned char *r;
730 726
731 727 for (r = p; *p; p++)
732 728 if (*p == '/')
733 729 r = p+1;
734 730 return (r);
735 731 }
736 732
737 733
738 734 /*
739 735 * validate_exrc - verify .exrc as belonging to the user.
740 736 * The file uid should match the process ruid,
741 737 * and the file should be writable only by the owner.
742 738 */
743 739 static int
744 740 validate_exrc(unsigned char *exrc_path)
745 741 {
746 742 struct stat64 exrc_stat;
747 743 int process_uid;
748 744
749 745 if (stat64((char *)exrc_path, &exrc_stat) == -1)
750 746 return (0); /* ignore if .exrec is not found */
751 747 process_uid = geteuid();
752 748 /* if not root, uid must match file owner */
753 749 if (process_uid && process_uid != exrc_stat.st_uid)
754 750 return (-1);
755 751 if ((exrc_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0)
756 752 return (-1);
757 753 return (0);
758 754 }
759 755
760 756 /*
761 757 * print usage message to stdout
762 758 */
763 759 static void
764 760 usage(unsigned char *name)
765 761 {
766 762 char buf[160];
767 763
768 764 #ifdef TRACE
769 765 (void) snprintf(buf, sizeof (buf), gettext(
770 766 "Usage: %s [- | -s] [-l] [-L] [-wn] "
771 767 "[-R] [-S] [-r [file]] [-t tag] [-T] [-U tracefile]\n"
772 768 "[-v] [-V] [-x] [-C] [+cmd | -c cmd] file...\n"), name);
773 769 #else
774 770 (void) snprintf(buf, sizeof (buf), gettext(
775 771 "Usage: %s [- | -s] [-l] [-L] [-wn] "
776 772 "[-R] [-S] [-r [file]] [-t tag]\n"
777 773 "[-v] [-V] [-x] [-C] [+cmd | -c cmd] file...\n"), name);
778 774 #endif
779 775 (void) write(2, buf, strlen(buf));
780 776 }
↓ open down ↓ |
525 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX