1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: file.c 1082 2008-06-12 18:39:50Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2016 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
18 * Program: High level file input and output routines
23 * The routines in this file
24 * handle the reading and writing of
25 * disk files. All of details about the
26 * reading and writing of the disk are
30 #include "../pith/charconv/filesys.h"
33 void init_insmsgchar_cbuf(void);
35 char *file_split(char *, size_t, char *, int);
38 * Read a file into the current
39 * buffer. This is really easy; all you do it
40 * find the name of the file, and call the standard
41 * "read a file into the current buffer" code.
45 fileread(int f
, int n
)
51 if ((s
=mlreply_utf8(_("Read file: "), fname
, NFILEN
, QNORML
, NULL
)) != TRUE
)
55 emlwrite(_("File reading disabled in secure mode"),NULL
);
59 if (strlen(fname
) == 0) {
60 emlwrite(_("No file name entered"),NULL
);
64 if((gmode
& MDTREE
) && !in_oper_tree(fname
)){
66 emlwrite(_("Can't read file from outside of %s"), &eml
);
70 return(readin(fname
, TRUE
, TRUE
));
75 static char *inshelptext
[] = {
76 /* TRANSLATORS: several lines of help text */
77 N_("Insert File Help Text"),
79 N_(" Type in a file name to have it inserted into your editing"),
80 N_(" buffer between the line that the cursor is currently on"),
81 N_(" and the line directly below it. You may abort this by "),
82 N_("~ typing the ~F~2 (~^~C) key after exiting help."),
84 N_("End of Insert File Help"),
89 static char *writehelp
[] = {
90 /* TRANSLATORS: several lines of help text */
91 N_("Write File Help Text"),
93 N_(" Type in a file name to have it written out, thus saving"),
94 N_(" your buffer, to a file. You can abort this by typing "),
95 N_("~ the ~F~2 (~^~C) key after exiting help."),
97 N_("End of Write File Help"),
105 * Insert a file into the current
106 * buffer. This is really easy; all you do it
107 * find the name of the file, and call the standard
108 * "insert a file into the current buffer" code.
109 * Bound to "C-X C-I".
112 insfile(int f
, int n
)
115 char fname
[NLINE
], dir
[NLINE
];
116 int retval
, bye
= 0, msg
= 0;
117 char prompt
[64], *infile
;
118 EXTRAKEYS menu_ins
[10];
121 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
122 return(rdonly()); /* we are in read only mode */
124 memset(&menu_ins
, 0, 10*sizeof(EXTRAKEYS
));
125 fname
[0] = dir
[0] = '\0';
127 /* set up keymenu stuff */
131 menu_ins
[last_menu
].name
= "^T";
132 menu_ins
[last_menu
].key
= (CTRL
|'T');
133 menu_ins
[last_menu
].label
= N_("To Files");
134 KS_OSDATASET(&menu_ins
[last_menu
], KS_NONE
);
136 if(Pmaster
&& Pmaster
->msgntext
){
137 menu_ins
[++last_menu
].name
= "^W";
138 menu_ins
[last_menu
].key
= (CTRL
|'W');
139 /* TRANSLATORS: Insert File is a key label for a command
140 that inserts a file into a message being composed.
141 InsertMsg means Insert Message and it inserts a different
142 message into the message being composed. */
143 menu_ins
[last_menu
].label
= msg
? N_("InsertFile") : N_("InsertMsg");
144 KS_OSDATASET(&menu_ins
[last_menu
], KS_NONE
);
147 #if !defined(DOS) && !defined(MAC)
148 if(Pmaster
&& Pmaster
->upload
){
149 menu_ins
[++last_menu
].name
= "^Y";
150 menu_ins
[last_menu
].key
= (CTRL
|'Y');
151 menu_ins
[last_menu
].label
= "RcvUpload";
152 KS_OSDATASET(&menu_ins
[last_menu
], KS_NONE
);
154 #endif /* !(DOS || MAC) */
157 menu_ins
[++last_menu
].name
= msg
? "" : "TAB";
158 menu_ins
[last_menu
].key
= (CTRL
|'I');
159 menu_ins
[last_menu
].label
= msg
? "" : N_("Complete");
160 KS_OSDATASET(&menu_ins
[last_menu
], KS_NONE
);
163 menu_ins
[++last_menu
].name
= NULL
;
166 snprintf(prompt
, sizeof(prompt
), "%s to insert from %s %s: ",
167 msg
? "Number of message" : "File",
168 (msg
|| (gmode
&MDCURDIR
))
170 : ((gmode
& MDTREE
) || opertree
[0]) ? opertree
: "home",
171 msg
? "folder" : "directory");
172 s
= mlreplyd_utf8(prompt
, fname
, NLINE
, QDEFLT
, msg
? NULL
: menu_ins
);
173 /* something to read and it was edited or the default accepted */
174 if(fname
[0] && (s
== TRUE
|| s
== FALSE
)){
177 init_insmsgchar_cbuf();
178 if((*Pmaster
->msgntext
)(atol(fname
), insmsgchar
)){
180 emlwrite(_("Message %s included"), &eml
);
186 emlwrite(_("Can't insert file in restricted mode"),NULL
);
190 && !compresspath(opertree
, fname
, sizeof(fname
))){
193 _("Can't insert file from outside of %s: too many ..'s"), &eml
);
196 fixpath(fname
, sizeof(fname
));
198 if((gmode
& MDTREE
) && !in_oper_tree(fname
)){
200 emlwrite(_("Can't insert file from outside of %s"), &eml
);
203 retval
= ifile(fname
);
215 fn
= file_split(dir
, sizeof(dir
), fname
, 0);
217 if(!pico_fncomplete(dir
, fn
, sizeof(fname
)-(fn
-fname
)))
223 msg
= !msg
; /* toggle what to insert */
227 emlwrite(_("Can't select messages yet!"), NULL
);
232 fn
= file_split(dir
, sizeof(dir
), fname
, 1);
233 if(!isdir(dir
, NULL
, NULL
)){
234 strncpy(dir
, (gmode
&MDCURDIR
)
235 ? (browse_dir
[0] ? browse_dir
: ".")
236 : ((gmode
& MDTREE
) || opertree
[0])
238 : (browse_dir
[0] ? browse_dir
239 :gethomedir(NULL
)), sizeof(dir
));
240 dir
[sizeof(dir
)-1] = '\0';
246 dirlen
= strlen(dir
);
247 if(dirlen
&& dir
[dirlen
- 1] != C_FILESEP
){
248 strncat(dir
, S_FILESEP
, sizeof(dir
)-strlen(dir
)-1);
249 dir
[sizeof(dir
)-1] = '\0';
252 strncat(dir
, fn
, sizeof(dir
)-strlen(dir
)-1);
253 dir
[sizeof(dir
)-1] = '\0';
254 if(!isdir(dir
, NULL
, NULL
))
255 dir
[MIN(dirlen
,sizeof(dir
)-1)] = '\0';
260 if((s
= FileBrowse(dir
, sizeof(dir
), fname
, sizeof(fname
),
261 NULL
, 0, FB_READ
, NULL
)) == 1){
263 emlwrite(_("Can't insert in restricted mode"),
270 len
= strlen(dir
)+strlen(S_FILESEP
)+strlen(fname
);
271 if ((infile
= (char *)malloc((len
+1)*sizeof(char))) != NULL
){
272 strncpy(infile
, dir
, len
);
274 strncat(infile
, S_FILESEP
, len
+1-1-strlen(infile
));
276 strncat(infile
, fname
, len
+1-1-strlen(infile
));
278 retval
= ifile(infile
);
279 free((char *) infile
);
282 emlwrite("Trouble allocating space for insert!"
292 pico_refresh(FALSE
, 1);
294 update(); /* redraw on return */
301 #if !defined(DOS) && !defined(MAC)
303 if(Pmaster
&& Pmaster
->upload
){
308 _("\007Restricted mode disallows uploaded command"),
314 retval
= (*Pmaster
->upload
)(tfname
, sizeof(tfname
), NULL
);
316 pico_refresh(FALSE
, 1);
320 retval
= ifile(tfname
);
324 sleep(3); /* problem, show error! */
326 if(tfname
[0]) /* clean up temp file */
330 (*term
.t_beep
)(); /* what? */
333 #endif /* !(DOS || MAC) */
336 VARS_TO_SAVE
*saved_state
;
338 saved_state
= save_pico_state();
339 (*Pmaster
->helper
)(msg
? Pmaster
->ins_m_help
341 _("Help for Insert File"), 1);
343 restore_pico_state(saved_state
);
344 free_pico_state(saved_state
);
348 pico_help(inshelptext
, _("Help for Insert File"), 1);
350 pico_refresh(FALSE
, 1);
360 curwp
->w_flag
|= WFMODE
|WFHARD
;
366 * split out the file name from the path.
367 * Copy path into dirbuf, return filename,
368 * which is a pointer into orig_fname.
369 * is_for_browse - use browse dir if possible
370 * don't want to use it for TAB-completion
373 file_split(char *dirbuf
, size_t dirbuflen
, char *orig_fname
, int is_for_browse
)
378 if(*orig_fname
&& (p
= strrchr(orig_fname
, C_FILESEP
))){
380 dirlen
= p
- orig_fname
;
382 strncpy(dirbuf
, S_FILESEP
, dirbuflen
);
383 dirbuf
[dirbuflen
-1] = '\0';
386 else if(orig_fname
[0] == C_FILESEP
387 || (isalpha((unsigned char)orig_fname
[0])
388 && orig_fname
[1] == ':')){
389 if(orig_fname
[1] == ':' && p
== orig_fname
+2)
390 dirlen
= fn
- orig_fname
;
392 dirlen
= MIN(dirlen
, dirbuflen
-1);
393 strncpy(dirbuf
, orig_fname
, dirlen
);
394 dirbuf
[dirlen
] = '\0';
397 else if (orig_fname
[0] == C_FILESEP
|| orig_fname
[0] == '~'){
398 dirlen
= MIN(dirlen
, dirbuflen
-1);
399 strncpy(dirbuf
, orig_fname
, dirlen
);
400 dirbuf
[dirlen
] = '\0';
404 snprintf(dirbuf
, dirbuflen
, "%s%c%.*s",
406 ? ((is_for_browse
&& browse_dir
[0]) ? browse_dir
: ".")
407 : ((gmode
& MDTREE
) || opertree
[0])
409 : ((is_for_browse
&& browse_dir
[0])
410 ? browse_dir
: gethomedir(NULL
)),
411 C_FILESEP
, (int) (p
- orig_fname
), orig_fname
);
415 strncpy(dirbuf
, (gmode
& MDCURDIR
)
416 ? ((is_for_browse
&& browse_dir
[0]) ? browse_dir
: ".")
417 : ((gmode
& MDTREE
) || opertree
[0])
419 : ((is_for_browse
&& browse_dir
[0])
420 ? browse_dir
: gethomedir(NULL
)), dirbuflen
);
421 dirbuf
[dirbuflen
-1] = '\0';
428 static CBUF_S insmsgchar_cb
;
431 init_insmsgchar_cbuf(void)
433 insmsgchar_cb
.cbuf
[0] = '\0';
434 insmsgchar_cb
.cbufp
= insmsgchar_cb
.cbuf
;
435 insmsgchar_cb
.cbufend
= insmsgchar_cb
.cbuf
;
440 * This is called with a stream of UTF-8 characters.
441 * We change that stream into UCS characters and insert
451 for(u
= glo_quote_str
; u
&& *u
; u
++)
455 else if(c
!= '\r'){ /* ignore CR (likely CR of CRLF) */
459 if((outchars
= utf8_to_ucs4_oneatatime(c
, &insmsgchar_cb
, &ucs
, NULL
)) != 0)
469 * Read file "fname" into the current
470 * buffer, blowing away any text found there. Called
471 * by both the read and find commands. Return the final
472 * status of the read. Also called by the mainline,
473 * to read in a file specified on the command line as
477 readin(char fname
[], /* name of file to read */
478 int lockfl
, /* check for file locks? */
479 int rename
) /* don't rename if reading from, say, alt speller */
481 UCS line
[NLINE
], *linep
;
483 int s
, done
, newline
;
485 curbp
->b_linecnt
= -1; /* Must be recalculated */
486 if ((s
= bclear(curbp
)) != TRUE
) /* Might be old. */
490 strncpy(curbp
->b_fname
, fname
, sizeof(curbp
->b_fname
));
491 curbp
->b_fname
[sizeof(curbp
->b_fname
)-1] = '\0';
494 if ((s
=ffropen(fname
)) != FIOSUC
){ /* Hard file open. */
495 if(s
== FIOFNF
) /* File not found. */
496 emlwrite(_("New file"), NULL
);
501 size_t charsread
= 0;
503 emlwrite(_("Reading file"), NULL
);
507 if((s
= ffgetline(line
, NLINE
, &charsread
, 1)) == FIOEOF
){
510 curbp
->b_flag
&= ~(BFTEMP
|BFCHG
);
513 snprintf(b
, sizeof(b
), _("Read %ld lines"), nline
);
515 snprintf(b
, sizeof(b
), _("Read 1 line"));
523 if(lnewline() == FALSE
){
536 for(linep
= line
; charsread
-- > 0; linep
++)
537 if(linsert(1, *linep
) == FALSE
) done
++;
547 ffclose(); /* Ignore errors. */
550 return(s
!= FIOERR
&& s
!= FIOFNF
); /* true if success */
555 * Ask for a file name, and write the
556 * contents of the current buffer to that file.
557 * Update the remembered file name and clear the
558 * buffer changed flag. This handling of file names
559 * is different from the earlier versions, and
560 * is more compatable with Gosling EMACS than
561 * with ITS EMACS. Bound to "C-X C-W".
564 filewrite(int f
, int n
)
569 char shows
[NLINE
], origshows
[NLINE
], *bufp
;
570 EXTRAKEYS menu_write
[10];
573 memset(&menu_write
, 0, 10*sizeof(EXTRAKEYS
));
574 if(curbp
->b_fname
[0] != 0){
575 strncpy(fname
, curbp
->b_fname
, sizeof(curbp
->b_fname
));
576 curbp
->b_fname
[sizeof(curbp
->b_fname
)-1] = '\0';
581 menu_write
[0].name
= "^T";
582 menu_write
[0].label
= N_("To Files");
583 menu_write
[0].key
= (CTRL
|'T');
584 menu_write
[1].name
= "TAB";
585 menu_write
[1].label
= N_("Complete");
586 menu_write
[1].key
= (CTRL
|'I');
587 menu_write
[2].name
= NULL
;
588 for(;!(gmode
& MDTOOL
);){
589 /* TRANSLATORS: Asking for name of file to write data into */
590 s
= mlreplyd_utf8(_("File Name to write : "), fname
, NFILEN
,
591 QDEFLT
|QFFILE
, menu_write
);
595 if(!fname
[0]){ /* no file name to write to */
600 if((gmode
& MDTREE
) && !compresspath(opertree
, fname
, sizeof(fname
))){
602 emlwrite(_("Can't write outside of %s: too many ..'s"), &eml
);
607 fixpath(fname
, sizeof(fname
)); /* fixup ~ in file name */
608 if((gmode
& MDTREE
) && !in_oper_tree(fname
)){
610 emlwrite(_("Can't write outside of %s"), &eml
);
620 char *fn
, *p
, dir
[NFILEN
];
624 if(*fname
&& (p
= strrchr(fname
, C_FILESEP
))){
628 strncpy(dir
, S_FILESEP
, sizeof(dir
));
629 dir
[sizeof(dir
)-1] = '\0';
632 else if(fname
[0] == C_FILESEP
633 || (isalpha((unsigned char)fname
[0])
636 else if (fname
[0] == C_FILESEP
|| fname
[0] == '~')
639 strncpy(dir
, fname
, MIN(p
- fname
, sizeof(dir
)-1));
640 dir
[MIN(p
-fname
, sizeof(dir
)-1)] = '\0';
643 snprintf(dir
, sizeof(dir
), "%s%c%.*s",
646 : ((gmode
& MDTREE
) || opertree
[0])
647 ? opertree
: gethomedir(NULL
),
648 C_FILESEP
, (int) (p
- fname
), fname
);
652 strncpy(dir
, (gmode
& MDCURDIR
)
654 : ((gmode
& MDTREE
) || opertree
[0])
655 ? opertree
: gethomedir(NULL
), sizeof(dir
));
656 dir
[sizeof(dir
)-1] = '\0';
659 if(!pico_fncomplete(dir
, fn
, sizeof(fname
)-(fn
-fname
)))
666 /* If we have a file name, break up into path and file name.*/
669 if(isdir(fname
, NULL
, NULL
)) {
670 /* fname is a directory. */
671 strncpy(shows
, fname
, sizeof(shows
));
672 shows
[sizeof(shows
)-1] = '\0';
676 /* Find right most separator. */
677 bufp
= strrchr (fname
, C_FILESEP
);
679 /* Copy directory part to 'shows', and file
680 * name part to front of 'fname'. */
682 strncpy(shows
, fname
, sizeof(shows
));
683 shows
[sizeof(shows
)-1] = '\0';
684 strncpy(fname
, bufp
+1, MIN(strlen(bufp
+1)+1, sizeof(fname
)));
685 fname
[sizeof(fname
)-1] = '\0';
690 /* If we did not end up with a valid directory, use home. */
691 if (!*shows
|| !isdir (shows
, NULL
, NULL
)){
692 strncpy(shows
, ((gmode
& MDTREE
) || opertree
[0])
694 : (browse_dir
[0] ? browse_dir
695 : gethomedir(NULL
)), sizeof(shows
));
696 shows
[sizeof(shows
)-1] = '\0';
699 strncpy(origshows
, shows
, sizeof(origshows
));
700 origshows
[sizeof(origshows
)-1] = '\0';
701 if ((s
= FileBrowse(shows
, sizeof(shows
), fname
, sizeof(fname
), NULL
, 0,
702 FB_SAVE
, NULL
)) == 1) {
703 if (strlen(shows
)+strlen(S_FILESEP
)+strlen(fname
) < NLINE
){
704 strncat(shows
, S_FILESEP
, sizeof(shows
)-strlen(shows
)-1);
705 shows
[sizeof(shows
)-1] = '\0';
706 strncat(shows
, fname
, sizeof(shows
)-strlen(shows
)-1);
707 shows
[sizeof(shows
)-1] = '\0';
708 strncpy(fname
, shows
, sizeof(fname
));
709 fname
[sizeof(fname
)-1] = '\0';
712 emlwrite("Cannot write. File name too long!!",NULL
);
716 else if (s
== 0 && strcmp(shows
, origshows
)){
717 strncat(shows
, S_FILESEP
, sizeof(shows
)-strlen(shows
)-1);
718 shows
[sizeof(shows
)-1] = '\0';
719 strncat(shows
, fname
, sizeof(shows
)-strlen(shows
)-1);
720 shows
[sizeof(shows
)-1] = '\0';
721 strncpy(fname
, shows
, sizeof(fname
));
722 fname
[sizeof(fname
)-1] = '\0';
725 emlwrite("Cannot write. File name too long!!",NULL
);
729 pico_refresh(FALSE
, 1);
737 pico_help(writehelp
, "", 1);
739 pico_refresh(FALSE
, 1);
748 if(strcmp(fname
, curbp
->b_fname
) == 0)
751 if((s
=fexist(fname
, "w", (off_t
*)NULL
)) == FIOSUC
){
752 /*exists overwrite? */
754 snprintf(shows
, sizeof(shows
), _("File \"%s\" exists, OVERWRITE"), fname
);
755 if((s
=mlyesno_utf8(shows
, FALSE
)) == TRUE
)
758 else if(s
== FIOFNF
){
759 break; /* go write it */
761 else{ /* some error, can't write */
767 emlwrite("Writing...", NULL
);
769 if ((s
=writeout(fname
, 0)) != -1) {
771 strncpy(curbp
->b_fname
, fname
, sizeof(curbp
->b_fname
));
772 curbp
->b_fname
[sizeof(curbp
->b_fname
)-1] = '\0';
773 curbp
->b_flag
&= ~BFCHG
;
775 wp
= wheadp
; /* Update mode lines. */
777 if (wp
->w_bufp
== curbp
)
778 if((Pmaster
&& s
== TRUE
) || Pmaster
== NULL
)
779 wp
->w_flag
|= WFMODE
;
786 emlwrite(_("Wrote %s lines"), &eml
);
789 emlwrite(_("Wrote 1 line"), NULL
);
792 return ((s
== -1) ? FALSE
: TRUE
);
797 * Save the contents of the current
798 * buffer in its associatd file. No nothing
799 * if nothing has changed (this may be a bug, not a
800 * feature). Error if there is no remembered file
801 * name for the buffer. Bound to "C-X C-S". May
802 * get called by "C-Z".
805 filesave(int f
, int n
)
811 if (curbp
->b_mode
&MDVIEW
) /* don't allow this command if */
812 return(rdonly()); /* we are in read only mode */
813 if ((curbp
->b_flag
&BFCHG
) == 0) /* Return, no changes. */
815 if (curbp
->b_fname
[0] == 0) { /* Must have a name. */
816 emlwrite(_("No file name"), NULL
);
821 emlwrite("Writing...", NULL
);
822 if ((s
=writeout(curbp
->b_fname
, 0)) != -1) {
823 curbp
->b_flag
&= ~BFCHG
;
824 wp
= wheadp
; /* Update mode lines. */
826 if (wp
->w_bufp
== curbp
)
828 wp
->w_flag
|= WFMODE
;
833 emlwrite(_("Wrote %s lines"), &eml
);
836 emlwrite(_("Wrote 1 line"), NULL
);
843 * This function performs the details of file
844 * writing. Uses the file management routines in the
845 * "fileio.c" package. The number of lines written is
846 * displayed. Sadly, it looks inside a LINE; provide
847 * a macro for this. Most of the grief is error
848 * checking of some sort.
850 * If the argument readonly is set, the file is created with user read
851 * and write permission only if it doesn't already exist. Note that the
852 * word readonly is misleading. It is user r/w permission only.
854 * CHANGES: 1 Aug 91: returns number of lines written or -1 on error, MSS
857 writeout(char *fn
, int readonly
)
864 if (!((s
= ffwopen(fn
, readonly
)) == FIOSUC
&& ffelbowroom()))
865 return (-1); /* Open writes message. */
867 lp
= lforw(curbp
->b_linep
); /* First line. */
868 nline
= 0; /* Number of lines. */
869 while (lp
!= curbp
->b_linep
) {
870 if ((s
=ffputline(&lp
->l_text
[0], llength(lp
))) != FIOSUC
)
876 t
= ffclose(); /* ffclose complains if error */
879 s
= t
; /* report worst case */
881 return ((s
== FIOSUC
) ? nline
: -1);
886 * writetmp - write a temporary file for message text, mindful of
887 * access restrictions and included text. If n is true, include
888 * lines that indicated included message text, otw forget them
889 * If dir is non-null, put the temp file in that directory.
892 writetmp(int n
, char *dir
)
894 static char fn
[NFILEN
];
902 /* Open writes message */
903 if (!fn
[0] || (s
=ffwopen(fn
, TRUE
)) != FIOSUC
){
910 lp
= lforw(curbp
->b_linep
); /* First line. */
911 nline
= 0; /* Number of lines. */
912 while (lp
!= curbp
->b_linep
) {
913 if(n
|| (!n
&& lp
->l_text
[0].c
!= '>'))
914 if ((s
=ffputline(&lp
->l_text
[0], llength(lp
))) != FIOSUC
)
921 t
= ffclose(); /* ffclose complains if error */
924 s
= t
; /* remember worst case */
926 if (s
!= FIOSUC
){ /* Some sort of error. */
936 * Insert file "fname" into the current
937 * buffer, Called by insert file command. Return the final
938 * status of the read.
943 UCS line
[NLINE
], *linep
;
945 int s
, done
, newline
;
946 size_t charsread
= 0;
949 if ((s
=ffropen(fname
)) != FIOSUC
){ /* Hard file open. */
956 curbp
->b_flag
|= BFCHG
; /* we have changed */
957 curbp
->b_flag
&= ~BFTEMP
; /* and are not temporary*/
958 curbp
->b_linecnt
= -1; /* must be recalculated */
961 emlwrite(_("Inserting %s."), &eml
);
965 if((s
= ffgetline(line
, NLINE
, &charsread
, 1)) == FIOEOF
){
968 if(llength(curwp
->w_dotp
) > curwp
->w_doto
)
974 snprintf(b
, sizeof(b
), _("Inserted %ld lines"), nline
);
976 snprintf(b
, sizeof(b
), _("Inserted 1 line"));
983 if(lnewline() == FALSE
){
991 case FIOSUC
: /* copy line into buf */
996 for(linep
= line
; charsread
-- > 0; linep
++)
997 if(linsert(1, *linep
) == FALSE
) done
++;
1006 ffclose(); /* Ignore errors. */
1008 return(s
!= FIOERR
);
1013 * pico_fncomplete - pico's function to complete the given file name
1016 pico_fncomplete(char *dirarg
, char *fn
, size_t fnlen
)
1018 char *p
, *dlist
, tmp
[NLINE
], dir
[NLINE
];
1019 int n
, i
, match
= -1;
1021 #define FILECMP(x, y) (toupper((unsigned char)(x))\
1022 == toupper((unsigned char)(y)))
1024 #define FILECMP(x, y) ((x) == (y))
1027 strncpy(dir
, dirarg
, sizeof(dir
));
1028 dir
[sizeof(dir
)-1] = '\0';
1029 pfnexpand(dir
, sizeof(dir
));
1030 if(*fn
&& (dlist
= p
= getfnames(dir
, fn
, &n
, NULL
, 0))){
1031 memset(tmp
, 0, sizeof(tmp
));
1032 while(n
--){ /* any names in it */
1033 for(i
= 0; i
< sizeof(tmp
)-1 && fn
[i
] && FILECMP(p
[i
], fn
[i
]); i
++)
1036 if(!fn
[i
]){ /* match or more? */
1038 for(; p
[i
] && FILECMP(p
[i
], tmp
[i
]); i
++)
1041 match
= !p
[i
] && !tmp
[i
];
1042 tmp
[i
] = '\0'; /* longest common string */
1045 match
= 1; /* may be it!?! */
1046 strncpy(tmp
, p
, sizeof(tmp
));
1047 tmp
[sizeof(tmp
)-1] = '\0';
1058 strncpy(fn
, tmp
, fnlen
);
1061 if ((strlen(dir
)+strlen(S_FILESEP
)+strlen(fn
)) < sizeof(dir
)){
1062 strncat(dir
, S_FILESEP
, sizeof(dir
)-strlen(dir
)-1);
1063 dir
[sizeof(dir
)-1] = '\0';
1064 strncat(dir
, fn
, sizeof(dir
)-strlen(dir
)-1);
1065 dir
[sizeof(dir
)-1] = '\0';
1066 if(isdir(dir
, NULL
, NULL
)){
1067 strncat(fn
, S_FILESEP
, fnlen
-strlen(fn
)-1);
1072 emlwrite("File name too BIG!!",0);
1085 * in_oper_tree - returns true if file "f" does reside in opertree
1088 in_oper_tree(char *f
)
1090 int end
= strlen(opertree
);
1092 return(!strncmp(opertree
, f
, end
)
1093 && (opertree
[end
-1] == '/'
1094 || opertree
[end
-1] == '\\'
1097 || f
[end
] == '\\'));