~ubuntu-branches/ubuntu/quantal/less/quantal

« back to all changes in this revision

Viewing changes to edit.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Schoepf
  • Date: 2002-04-04 16:43:52 UTC
  • Revision ID: james.westby@ubuntu.com-20020404164352-qldq048yoc7x5sd5
Tags: upstream-374
ImportĀ upstreamĀ versionĀ 374

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1984-2000  Mark Nudelman
 
3
 *
 
4
 * You may distribute under the terms of either the GNU General Public
 
5
 * License or the Less License, as specified in the README file.
 
6
 *
 
7
 * For more information about less, or for information on how to 
 
8
 * contact the author, see the README file.
 
9
 */
 
10
 
 
11
 
 
12
#include "less.h"
 
13
 
 
14
public int fd0 = 0;
 
15
 
 
16
extern int new_file;
 
17
extern int errmsgs;
 
18
extern int cbufs;
 
19
extern char *every_first_cmd;
 
20
extern int any_display;
 
21
extern int force_open;
 
22
extern int is_tty;
 
23
extern int sigs;
 
24
extern IFILE curr_ifile;
 
25
extern IFILE old_ifile;
 
26
extern struct scrpos initial_scrpos;
 
27
extern void constant *ml_examine;
 
28
#if SPACES_IN_FILENAMES
 
29
extern char openquote;
 
30
extern char closequote;
 
31
#endif
 
32
 
 
33
#if LOGFILE
 
34
extern int logfile;
 
35
extern int force_logfile;
 
36
extern char *namelogfile;
 
37
#endif
 
38
 
 
39
char *curr_altfilename = NULL;
 
40
static void *curr_altpipe;
 
41
 
 
42
 
 
43
/*
 
44
 * Textlist functions deal with a list of words separated by spaces.
 
45
 * init_textlist sets up a textlist structure.
 
46
 * forw_textlist uses that structure to iterate thru the list of
 
47
 * words, returning each one as a standard null-terminated string.
 
48
 * back_textlist does the same, but runs thru the list backwards.
 
49
 */
 
50
        public void
 
51
init_textlist(tlist, str)
 
52
        struct textlist *tlist;
 
53
        char *str;
 
54
{
 
55
        char *s;
 
56
#if SPACES_IN_FILENAMES
 
57
        int meta_quoted = 0;
 
58
        int delim_quoted = 0;
 
59
        char *esc = get_meta_escape();
 
60
        int esclen = strlen(esc);
 
61
#endif
 
62
        
 
63
        tlist->string = skipsp(str);
 
64
        tlist->endstring = tlist->string + strlen(tlist->string);
 
65
        for (s = str;  s < tlist->endstring;  s++)
 
66
        {
 
67
#if SPACES_IN_FILENAMES
 
68
                if (meta_quoted)
 
69
                {
 
70
                        meta_quoted = 0;
 
71
                } else if (esclen > 0 && s + esclen < tlist->endstring &&
 
72
                           strncmp(s, esc, esclen) == 0)
 
73
                {
 
74
                        meta_quoted = 1;
 
75
                        s += esclen - 1;
 
76
                } else if (delim_quoted)
 
77
                {
 
78
                        if (*s == closequote)
 
79
                                delim_quoted = 0;
 
80
                } else /* (!delim_quoted) */
 
81
                {
 
82
                        if (*s == openquote)
 
83
                                delim_quoted = 1;
 
84
                        else if (*s == ' ')
 
85
                                *s = '\0';
 
86
                }
 
87
#else
 
88
                if (*s == ' ')
 
89
                        *s = '\0';
 
90
#endif
 
91
        }
 
92
}
 
93
 
 
94
        public char *
 
95
forw_textlist(tlist, prev)
 
96
        struct textlist *tlist;
 
97
        char *prev;
 
98
{
 
99
        char *s;
 
100
        
 
101
        /*
 
102
         * prev == NULL means return the first word in the list.
 
103
         * Otherwise, return the word after "prev".
 
104
         */
 
105
        if (prev == NULL)
 
106
                s = tlist->string;
 
107
        else
 
108
                s = prev + strlen(prev);
 
109
        if (s >= tlist->endstring)
 
110
                return (NULL);
 
111
        while (*s == '\0')
 
112
                s++;
 
113
        if (s >= tlist->endstring)
 
114
                return (NULL);
 
115
        return (s);
 
116
}
 
117
 
 
118
        public char *
 
119
back_textlist(tlist, prev)
 
120
        struct textlist *tlist;
 
121
        char *prev;
 
122
{
 
123
        char *s;
 
124
        
 
125
        /*
 
126
         * prev == NULL means return the last word in the list.
 
127
         * Otherwise, return the word before "prev".
 
128
         */
 
129
        if (prev == NULL)
 
130
                s = tlist->endstring;
 
131
        else if (prev <= tlist->string)
 
132
                return (NULL);
 
133
        else
 
134
                s = prev - 1;
 
135
        while (*s == '\0')
 
136
                s--;
 
137
        if (s <= tlist->string)
 
138
                return (NULL);
 
139
        while (s[-1] != '\0' && s > tlist->string)
 
140
                s--;
 
141
        return (s);
 
142
}
 
143
 
 
144
/*
 
145
 * Close the current input file.
 
146
 */
 
147
        static void
 
148
close_file()
 
149
{
 
150
        struct scrpos scrpos;
 
151
        
 
152
        if (curr_ifile == NULL_IFILE)
 
153
                return;
 
154
 
 
155
        /*
 
156
         * Save the current position so that we can return to
 
157
         * the same position if we edit this file again.
 
158
         */
 
159
        get_scrpos(&scrpos);
 
160
        if (scrpos.pos != NULL_POSITION)
 
161
        {
 
162
                store_pos(curr_ifile, &scrpos);
 
163
                lastmark();
 
164
        }
 
165
        /*
 
166
         * Close the file descriptor, unless it is a pipe.
 
167
         */
 
168
        ch_close();
 
169
        /*
 
170
         * If we opened a file using an alternate name,
 
171
         * do special stuff to close it.
 
172
         */
 
173
        if (curr_altfilename != NULL)
 
174
        {
 
175
                close_altfile(curr_altfilename, get_filename(curr_ifile),
 
176
                                curr_altpipe);
 
177
                free(curr_altfilename);
 
178
                curr_altfilename = NULL;
 
179
        }
 
180
        curr_ifile = NULL_IFILE;
 
181
}
 
182
 
 
183
/*
 
184
 * Edit a new file (given its name).
 
185
 * Filename == "-" means standard input.
 
186
 * Filename == NULL means just close the current file.
 
187
 */
 
188
        public int
 
189
edit(filename)
 
190
        char *filename;
 
191
{
 
192
        if (filename == NULL)
 
193
                return (edit_ifile(NULL_IFILE));
 
194
        return (edit_ifile(get_ifile(filename, curr_ifile)));
 
195
}
 
196
        
 
197
/*
 
198
 * Edit a new file (given its IFILE).
 
199
 * ifile == NULL means just close the current file.
 
200
 */
 
201
        public int
 
202
edit_ifile(ifile)
 
203
        IFILE ifile;
 
204
{
 
205
        int f;
 
206
        int answer;
 
207
        int no_display;
 
208
        int chflags;
 
209
        char *filename;
 
210
        char *open_filename;
 
211
        char *qopen_filename;
 
212
        char *alt_filename;
 
213
        void *alt_pipe;
 
214
        IFILE was_curr_ifile;
 
215
        PARG parg;
 
216
                
 
217
        if (ifile == curr_ifile)
 
218
        {
 
219
                /*
 
220
                 * Already have the correct file open.
 
221
                 */
 
222
                return (0);
 
223
        }
 
224
 
 
225
        /*
 
226
         * We must close the currently open file now.
 
227
         * This is necessary to make the open_altfile/close_altfile pairs
 
228
         * nest properly (or rather to avoid nesting at all).
 
229
         * {{ Some stupid implementations of popen() mess up if you do:
 
230
         *    fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }}
 
231
         */
 
232
#if LOGFILE
 
233
        end_logfile();
 
234
#endif
 
235
        was_curr_ifile = save_curr_ifile();
 
236
        if (curr_ifile != NULL_IFILE)
 
237
        {
 
238
                chflags = ch_getflags();
 
239
                close_file();
 
240
                if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
 
241
                {
 
242
                        /*
 
243
                         * Don't keep the help file in the ifile list.
 
244
                         */
 
245
                        del_ifile(was_curr_ifile);
 
246
                        was_curr_ifile = old_ifile;
 
247
                }
 
248
        }
 
249
 
 
250
        if (ifile == NULL_IFILE)
 
251
        {
 
252
                /*
 
253
                 * No new file to open.
 
254
                 * (Don't set old_ifile, because if you call edit_ifile(NULL),
 
255
                 *  you're supposed to have saved curr_ifile yourself,
 
256
                 *  and you'll restore it if necessary.)
 
257
                 */
 
258
                unsave_ifile(was_curr_ifile);
 
259
                return (0);
 
260
        }
 
261
 
 
262
        filename = save(get_filename(ifile));
 
263
        /*
 
264
         * See if LESSOPEN specifies an "alternate" file to open.
 
265
         */
 
266
        alt_pipe = NULL;
 
267
        alt_filename = open_altfile(filename, &f, &alt_pipe);
 
268
        open_filename = (alt_filename != NULL) ? alt_filename : filename;
 
269
        qopen_filename = shell_unquote(open_filename);
 
270
 
 
271
        chflags = 0;
 
272
        if (alt_pipe != NULL)
 
273
        {
 
274
                /*
 
275
                 * The alternate "file" is actually a pipe.
 
276
                 * f has already been set to the file descriptor of the pipe
 
277
                 * in the call to open_altfile above.
 
278
                 * Keep the file descriptor open because it was opened 
 
279
                 * via popen(), and pclose() wants to close it.
 
280
                 */
 
281
                chflags |= CH_POPENED;
 
282
        } else if (strcmp(open_filename, "-") == 0)
 
283
        {
 
284
                /* 
 
285
                 * Use standard input.
 
286
                 * Keep the file descriptor open because we can't reopen it.
 
287
                 */
 
288
                f = fd0;
 
289
                chflags |= CH_KEEPOPEN;
 
290
                /*
 
291
                 * Must switch stdin to BINARY mode.
 
292
                 */
 
293
                SET_BINARY(f);
 
294
#if MSDOS_COMPILER==DJGPPC
 
295
                /*
 
296
                 * Setting stdin to binary by default causes
 
297
                 * Ctrl-C to not raise SIGINT.  We must undo
 
298
                 * that side-effect.
 
299
                 */
 
300
                __djgpp_set_ctrl_c(1);
 
301
#endif
 
302
        } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
 
303
        {
 
304
                f = -1;
 
305
                chflags |= CH_HELPFILE;
 
306
        } else if ((parg.p_string = bad_file(open_filename)) != NULL)
 
307
        {
 
308
                /*
 
309
                 * It looks like a bad file.  Don't try to open it.
 
310
                 */
 
311
                error("%s", &parg);
 
312
                free(parg.p_string);
 
313
            err1:
 
314
                if (alt_filename != NULL)
 
315
                {
 
316
                        close_altfile(alt_filename, filename, alt_pipe);
 
317
                        free(alt_filename);
 
318
                }
 
319
                del_ifile(ifile);
 
320
                free(qopen_filename);
 
321
                free(filename);
 
322
                /*
 
323
                 * Re-open the current file.
 
324
                 */
 
325
                reedit_ifile(was_curr_ifile);
 
326
                return (1);
 
327
        } else if ((f = open(qopen_filename, OPEN_READ)) < 0)
 
328
        {
 
329
                /*
 
330
                 * Got an error trying to open it.
 
331
                 */
 
332
                parg.p_string = errno_message(filename);
 
333
                error("%s", &parg);
 
334
                free(parg.p_string);
 
335
                goto err1;
 
336
        } else 
 
337
        {
 
338
                chflags |= CH_CANSEEK;
 
339
                if (!force_open && !opened(ifile) && bin_file(f))
 
340
                {
 
341
                        /*
 
342
                         * Looks like a binary file.  
 
343
                         * Ask user if we should proceed.
 
344
                         */
 
345
                        parg.p_string = filename;
 
346
                        answer = query("\"%s\" may be a binary file.  See it anyway? ",
 
347
                                &parg);
 
348
                        if (answer != 'y' && answer != 'Y')
 
349
                        {
 
350
                                close(f);
 
351
                                goto err1;
 
352
                        }
 
353
                }
 
354
        }
 
355
        free(qopen_filename);
 
356
 
 
357
        /*
 
358
         * Get the new ifile.
 
359
         * Get the saved position for the file.
 
360
         */
 
361
        if (was_curr_ifile != NULL_IFILE)
 
362
        {
 
363
                old_ifile = was_curr_ifile;
 
364
                unsave_ifile(was_curr_ifile);
 
365
        }
 
366
        curr_ifile = ifile;
 
367
        curr_altfilename = alt_filename;
 
368
        curr_altpipe = alt_pipe;
 
369
        set_open(curr_ifile); /* File has been opened */
 
370
        get_pos(curr_ifile, &initial_scrpos);
 
371
        new_file = TRUE;
 
372
        ch_init(f, chflags);
 
373
 
 
374
        if (!(chflags & CH_HELPFILE))
 
375
        {
 
376
#if LOGFILE
 
377
                if (namelogfile != NULL && is_tty)
 
378
                        use_logfile(namelogfile);
 
379
#endif
 
380
                if (every_first_cmd != NULL)
 
381
                        ungetsc(every_first_cmd);
 
382
        }
 
383
 
 
384
        no_display = !any_display;
 
385
        flush();
 
386
        any_display = TRUE;
 
387
 
 
388
        if (is_tty)
 
389
        {
 
390
                /*
 
391
                 * Output is to a real tty.
 
392
                 */
 
393
 
 
394
                /*
 
395
                 * Indicate there is nothing displayed yet.
 
396
                 */
 
397
                pos_clear();
 
398
                clr_linenum();
 
399
#if HILITE_SEARCH
 
400
                clr_hilite();
 
401
#endif
 
402
                cmd_addhist(ml_examine, filename);
 
403
                if (no_display && errmsgs > 0)
 
404
                {
 
405
                        /*
 
406
                         * We displayed some messages on error output
 
407
                         * (file descriptor 2; see error() function).
 
408
                         * Before erasing the screen contents,
 
409
                         * display the file name and wait for a keystroke.
 
410
                         */
 
411
                        parg.p_string = filename;
 
412
                        error("%s", &parg);
 
413
                }
 
414
        }
 
415
        free(filename);
 
416
        return (0);
 
417
}
 
418
 
 
419
/*
 
420
 * Edit a space-separated list of files.
 
421
 * For each filename in the list, enter it into the ifile list.
 
422
 * Then edit the first one.
 
423
 */
 
424
        public int
 
425
edit_list(filelist)
 
426
        char *filelist;
 
427
{
 
428
        IFILE save_ifile;
 
429
        char *good_filename;
 
430
        char *filename;
 
431
        char *gfilelist;
 
432
        char *gfilename;
 
433
        struct textlist tl_files;
 
434
        struct textlist tl_gfiles;
 
435
 
 
436
        save_ifile = save_curr_ifile();
 
437
        good_filename = NULL;
 
438
        
 
439
        /*
 
440
         * Run thru each filename in the list.
 
441
         * Try to glob the filename.  
 
442
         * If it doesn't expand, just try to open the filename.
 
443
         * If it does expand, try to open each name in that list.
 
444
         */
 
445
        init_textlist(&tl_files, filelist);
 
446
        filename = NULL;
 
447
        while ((filename = forw_textlist(&tl_files, filename)) != NULL)
 
448
        {
 
449
                gfilelist = lglob(filename);
 
450
                init_textlist(&tl_gfiles, gfilelist);
 
451
                gfilename = NULL;
 
452
                while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
 
453
                {
 
454
                        if (edit(gfilename) == 0 && good_filename == NULL)
 
455
                                good_filename = get_filename(curr_ifile);
 
456
                }
 
457
                free(gfilelist);
 
458
        }
 
459
        /*
 
460
         * Edit the first valid filename in the list.
 
461
         */
 
462
        if (good_filename == NULL)
 
463
        {
 
464
                unsave_ifile(save_ifile);
 
465
                return (1);
 
466
        }
 
467
        if (get_ifile(good_filename, curr_ifile) == curr_ifile)
 
468
        {
 
469
                /*
 
470
                 * Trying to edit the current file; don't reopen it.
 
471
                 */
 
472
                unsave_ifile(save_ifile);
 
473
                return (0);
 
474
        }
 
475
        reedit_ifile(save_ifile);
 
476
        return (edit(good_filename));
 
477
}
 
478
 
 
479
/*
 
480
 * Edit the first file in the command line (ifile) list.
 
481
 */
 
482
        public int
 
483
edit_first()
 
484
{
 
485
        curr_ifile = NULL_IFILE;
 
486
        return (edit_next(1));
 
487
}
 
488
 
 
489
/*
 
490
 * Edit the last file in the command line (ifile) list.
 
491
 */
 
492
        public int
 
493
edit_last()
 
494
{
 
495
        curr_ifile = NULL_IFILE;
 
496
        return (edit_prev(1));
 
497
}
 
498
 
 
499
 
 
500
/*
 
501
 * Edit the next or previous file in the command line (ifile) list.
 
502
 */
 
503
        static int
 
504
edit_istep(h, n, dir)
 
505
        IFILE h;
 
506
        int n;
 
507
        int dir;
 
508
{
 
509
        IFILE next;
 
510
 
 
511
        /*
 
512
         * Skip n filenames, then try to edit each filename.
 
513
         */
 
514
        for (;;)
 
515
        {
 
516
                next = (dir > 0) ? next_ifile(h) : prev_ifile(h);
 
517
                if (--n < 0)
 
518
                {
 
519
                        if (edit_ifile(h) == 0)
 
520
                                break;
 
521
                }
 
522
                if (next == NULL_IFILE)
 
523
                {
 
524
                        /*
 
525
                         * Reached end of the ifile list.
 
526
                         */
 
527
                        return (1);
 
528
                }
 
529
                if (ABORT_SIGS())
 
530
                {
 
531
                        /*
 
532
                         * Interrupt breaks out, if we're in a long
 
533
                         * list of files that can't be opened.
 
534
                         */
 
535
                        return (1);
 
536
                }
 
537
                h = next;
 
538
        } 
 
539
        /*
 
540
         * Found a file that we can edit.
 
541
         */
 
542
        return (0);
 
543
}
 
544
 
 
545
        static int
 
546
edit_inext(h, n)
 
547
        IFILE h;
 
548
        int n;
 
549
{
 
550
        return (edit_istep(h, n, 1));
 
551
}
 
552
 
 
553
        public int
 
554
edit_next(n)
 
555
        int n;
 
556
{
 
557
        return edit_istep(curr_ifile, n, 1);
 
558
}
 
559
 
 
560
        static int
 
561
edit_iprev(h, n)
 
562
        IFILE h;
 
563
        int n;
 
564
{
 
565
        return (edit_istep(h, n, -1));
 
566
}
 
567
 
 
568
        public int
 
569
edit_prev(n)
 
570
        int n;
 
571
{
 
572
        return edit_istep(curr_ifile, n, -1);
 
573
}
 
574
 
 
575
/*
 
576
 * Edit a specific file in the command line (ifile) list.
 
577
 */
 
578
        public int
 
579
edit_index(n)
 
580
        int n;
 
581
{
 
582
        IFILE h;
 
583
 
 
584
        h = NULL_IFILE;
 
585
        do
 
586
        {
 
587
                if ((h = next_ifile(h)) == NULL_IFILE)
 
588
                {
 
589
                        /*
 
590
                         * Reached end of the list without finding it.
 
591
                         */
 
592
                        return (1);
 
593
                }
 
594
        } while (get_index(h) != n);
 
595
 
 
596
        return (edit_ifile(h));
 
597
}
 
598
 
 
599
        public IFILE
 
600
save_curr_ifile()
 
601
{
 
602
        if (curr_ifile != NULL_IFILE)
 
603
                hold_ifile(curr_ifile, 1);
 
604
        return (curr_ifile);
 
605
}
 
606
 
 
607
        public void
 
608
unsave_ifile(save_ifile)
 
609
        IFILE save_ifile;
 
610
{
 
611
        if (save_ifile != NULL_IFILE)
 
612
                hold_ifile(save_ifile, -1);
 
613
}
 
614
 
 
615
/*
 
616
 * Reedit the ifile which was previously open.
 
617
 */
 
618
        public void
 
619
reedit_ifile(save_ifile)
 
620
        IFILE save_ifile;
 
621
{
 
622
        IFILE next;
 
623
        IFILE prev;
 
624
 
 
625
        /*
 
626
         * Try to reopen the ifile.
 
627
         * Note that opening it may fail (maybe the file was removed),
 
628
         * in which case the ifile will be deleted from the list.
 
629
         * So save the next and prev ifiles first.
 
630
         */
 
631
        unsave_ifile(save_ifile);
 
632
        next = next_ifile(save_ifile);
 
633
        prev = prev_ifile(save_ifile);
 
634
        if (edit_ifile(save_ifile) == 0)
 
635
                return;
 
636
        /*
 
637
         * If can't reopen it, open the next input file in the list.
 
638
         */
 
639
        if (next != NULL_IFILE && edit_inext(next, 0) == 0)
 
640
                return;
 
641
        /*
 
642
         * If can't open THAT one, open the previous input file in the list.
 
643
         */
 
644
        if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0)
 
645
                return;
 
646
        /*
 
647
         * If can't even open that, we're stuck.  Just quit.
 
648
         */
 
649
        quit(QUIT_ERROR);
 
650
}
 
651
 
 
652
/*
 
653
 * Edit standard input.
 
654
 */
 
655
        public int
 
656
edit_stdin()
 
657
{
 
658
        if (isatty(fd0))
 
659
        {
 
660
                error("Missing filename (\"less --help\" for help)", NULL_PARG);
 
661
                quit(QUIT_OK);
 
662
        }
 
663
        return (edit("-"));
 
664
}
 
665
 
 
666
/*
 
667
 * Copy a file directly to standard output.
 
668
 * Used if standard output is not a tty.
 
669
 */
 
670
        public void
 
671
cat_file()
 
672
{
 
673
        register int c;
 
674
 
 
675
        while ((c = ch_forw_get()) != EOI)
 
676
                putchr(c);
 
677
        flush();
 
678
}
 
679
 
 
680
#if LOGFILE
 
681
 
 
682
/*
 
683
 * If the user asked for a log file and our input file
 
684
 * is standard input, create the log file.  
 
685
 * We take care not to blindly overwrite an existing file.
 
686
 */
 
687
        public void
 
688
use_logfile(filename)
 
689
        char *filename;
 
690
{
 
691
        register int exists;
 
692
        register int answer;
 
693
        PARG parg;
 
694
 
 
695
        if (ch_getflags() & CH_CANSEEK)
 
696
                /*
 
697
                 * Can't currently use a log file on a file that can seek.
 
698
                 */
 
699
                return;
 
700
 
 
701
        /*
 
702
         * {{ We could use access() here. }}
 
703
         */
 
704
        filename = shell_unquote(filename);
 
705
        exists = open(filename, OPEN_READ);
 
706
        close(exists);
 
707
        exists = (exists >= 0);
 
708
 
 
709
        /*
 
710
         * Decide whether to overwrite the log file or append to it.
 
711
         * If it doesn't exist we "overwrite" it.
 
712
         */
 
713
        if (!exists || force_logfile)
 
714
        {
 
715
                /*
 
716
                 * Overwrite (or create) the log file.
 
717
                 */
 
718
                answer = 'O';
 
719
        } else
 
720
        {
 
721
                /*
 
722
                 * Ask user what to do.
 
723
                 */
 
724
                parg.p_string = filename;
 
725
                answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg);
 
726
        }
 
727
 
 
728
loop:
 
729
        switch (answer)
 
730
        {
 
731
        case 'O': case 'o':
 
732
                /*
 
733
                 * Overwrite: create the file.
 
734
                 */
 
735
                logfile = creat(filename, 0644);
 
736
                break;
 
737
        case 'A': case 'a':
 
738
                /*
 
739
                 * Append: open the file and seek to the end.
 
740
                 */
 
741
                logfile = open(filename, OPEN_APPEND);
 
742
                if (lseek(logfile, (off_t)0, 2) == BAD_LSEEK)
 
743
                {
 
744
                        close(logfile);
 
745
                        logfile = -1;
 
746
                }
 
747
                break;
 
748
        case 'D': case 'd':
 
749
                /*
 
750
                 * Don't do anything.
 
751
                 */
 
752
                free(filename);
 
753
                return;
 
754
        case 'q':
 
755
                quit(QUIT_OK);
 
756
                /*NOTREACHED*/
 
757
        default:
 
758
                /*
 
759
                 * Eh?
 
760
                 */
 
761
                answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG);
 
762
                goto loop;
 
763
        }
 
764
 
 
765
        if (logfile < 0)
 
766
        {
 
767
                /*
 
768
                 * Error in opening logfile.
 
769
                 */
 
770
                parg.p_string = filename;
 
771
                error("Cannot write to \"%s\"", &parg);
 
772
                free(filename);
 
773
                return;
 
774
        }
 
775
        free(filename);
 
776
        SET_BINARY(logfile);
 
777
}
 
778
 
 
779
#endif