1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #ifdef HAVE_CONFIG_H
32 #include "../config.h"
33 #endif
34
35 #include "fileUtils.h"
36 #include "utils.h"
37 #include "nedit_malloc.h"
38
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <errno.h>
43 #include <X11/Intrinsic.h>
44 #include <sys/types.h>
45 #include <sys/param.h>
46 #include <sys/stat.h>
47 #include <unistd.h>
48 #include <pwd.h>
49
50 #ifdef HAVE_DEBUG_H
51 #include "../debug.h"
52 #endif
53
54 #ifndef MAXSYMLINKS
55 #define MAXSYMLINKS 20
56 #endif
57
58 #define TRUE 1
59 #define FALSE 0
60
61
62
63
64
65
66 #define FORMAT_SAMPLE_LINES 5
67 #define FORMAT_SAMPLE_CHARS 2000
68
69 static char *nextSlash(
char *ptr);
70 static char *prevSlash(
char *ptr);
71 static int compareThruSlash(
const char *string1,
const char *string2);
72 static void copyThruSlash(
char **toString,
char **fromString);
73
74
75
76
77
78
79
80
81
82 int
83 ParseFilename(
const char *fullname,
char *filename,
char *pathname)
84 {
85 int fullLen = strlen(fullname);
86 int i, pathLen, fileLen;
87
88 char *viewExtendPath;
89 int scanStart;
90
91
92
93 if ((viewExtendPath = strstr(fullname,
"@@/")) !=
NULL)
94 scanStart = viewExtendPath - fullname -
1;
95 else
96 scanStart = fullLen -
1;
97
98
99 for (i=scanStart; i>=
0; i--) {
100 if (fullname[i] ==
'/')
101 break;
102 }
103
104
105 pathLen = i +
1;
106 fileLen = fullLen - pathLen;
107 if (pathname) {
108 if (pathLen >=
MAXPATHLEN) {
109 return 1;
110 }
111 strncpy(pathname, fullname, pathLen);
112 pathname[pathLen] =
0;
113 }
114 if (filename) {
115 if (fileLen >=
MAXPATHLEN) {
116 return 2;
117 }
118 strncpy(filename, &fullname[pathLen], fileLen);
119 filename[fileLen] =
0;
120 }
121
122 #ifndef VMS
123 if(pathname) {
124 if (NormalizePathname(pathname)) {
125 return 1;
126 }
127 pathLen = strlen(pathname);
128 }
129 #endif
130
131 if (filename && pathname && ((pathLen +
1 + fileLen) >=
MAXPATHLEN)) {
132 return 1;
133 }
134 return 0;
135 }
136
137 #ifndef VMS
138
139
140
141
142
143
144
145 int
146 ExpandTilde(
char *pathname)
147 {
148 struct passwd *passwdEntry;
149 char username[
MAXPATHLEN], temp[
MAXPATHLEN];
150 char *nameEnd;
151 unsigned len_left;
152
153 if (pathname[
0] !=
'~')
154 return TRUE;
155 nameEnd = strchr(&pathname[
1],
'/');
156 if (nameEnd ==
NULL) {
157 nameEnd = pathname + strlen(pathname);
158 }
159 strncpy(username, &pathname[
1], nameEnd - &pathname[
1]);
160 username[nameEnd - &pathname[
1]] =
'\0';
161
162
163 if (username[
0] ==
'\0') {
164 passwdEntry = getpwuid(getuid());
165 if ((passwdEntry ==
NULL) || (*(passwdEntry->pw_dir)==
'\0')) {
166
167 perror(
"XNEdit/nc: getpwuid() failed ");
168 exit(
EXIT_FAILURE);
169 }
170 }
171 else {
172 passwdEntry = getpwnam(username);
173 if ((passwdEntry ==
NULL) || (*(passwdEntry->pw_dir)==
'\0')) {
174
175
176 return FALSE;
177 }
178 }
179
180 strcpy(temp, passwdEntry->pw_dir);
181 strcat(temp,
"/");
182 len_left=
sizeof(temp)-strlen(temp)-
1;
183 if (len_left < strlen(nameEnd)) {
184
185 return FALSE;
186 }
187 strcat(temp, nameEnd);
188 strcpy(pathname, temp);
189 return TRUE;
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 int
207 ResolvePath(
const char * pathIn,
char * pathResolved)
208 {
209 char resolveBuf[
MAXPATHLEN], pathBuf[
MAXPATHLEN];
210 char *pathEnd;
211 int rlResult, loops;
212
213 #ifdef NO_READLINK
214 strncpy(pathResolved, pathIn,
MAXPATHLEN);
215
216 return TRUE;
217 #else
218
219 for (loops=
0; loops<
MAXSYMLINKS; loops++) {
220 #ifdef UNICOS
221 rlResult=readlink((
char *)pathIn, resolveBuf,
MAXPATHLEN-
1);
222 #else
223 rlResult=readlink(pathIn, resolveBuf,
MAXPATHLEN-
1);
224 #endif
225 if (rlResult<
0) {
226
227 #ifndef __Lynx__
228 if (errno ==
EINVAL)
229 #else
230 if (errno ==
ENXIO)
231 #endif
232 {
233
234 strncpy(pathResolved, pathIn,
MAXPATHLEN);
235 pathResolved[
MAXPATHLEN-
1] =
'\0';
236 return TRUE;
237 }
else {
238 return FALSE;
239 }
240 }
else if (rlResult ==
0) {
241 return FALSE;
242 }
243
244 resolveBuf[rlResult]=
0;
245
246 if (resolveBuf[
0]!=
'/') {
247 strncpy(pathBuf, pathIn,
MAXPATHLEN);
248 pathBuf[
MAXPATHLEN-
1] =
'\0';
249 pathEnd=strrchr(pathBuf,
'/');
250 if (!pathEnd) {
251 return FALSE;
252 }
253 strcpy(pathEnd+
1, resolveBuf);
254 }
else {
255 strcpy(pathBuf, resolveBuf);
256 }
257 NormalizePathname(pathBuf);
258 pathIn=pathBuf;
259 }
260
261 return FALSE;
262 #endif
263 }
264
265
266
267
268
269
270
271
272
273 int NormalizePathname(
char *pathname)
274 {
275
276 #ifdef __EMX__
277
278 if (!_fnisabs(pathname)) {
279 #else
280 if (pathname[
0] !=
'/') {
281 #endif
282 char *oldPathname;
283 size_t len;
284
285
286 oldPathname=(
char *)malloc(strlen(pathname)+
1);
287 strcpy(oldPathname, pathname);
288
289 strcpy(pathname, GetCurrentDir());
290
291
292
293
294 len = strlen(pathname);
295
296
297
298
299
300 if (
0 == len ?
1 : pathname[len-
1] !=
'/')
301 {
302 strcat(pathname,
"/");
303 }
304 strcat(pathname, oldPathname);
305 free(oldPathname);
306 }
307
308
309 return CompressPathname(pathname);
310 }
311
312
313
314
315
316
317
318
319 int CompressPathname(
char *pathname)
320 {
321 char *buf, *inPtr, *outPtr;
322 struct stat statbuf;
323
324
325
326
327
328
329
330
331 inPtr = pathname;
332 buf = (
char*) malloc(strlen(pathname) +
2);
333 outPtr = buf;
334 *outPtr++ = *inPtr++;
335 while (*inPtr)
336 {
337 *outPtr = *inPtr++;
338 if (
'/' == *outPtr)
339 {
340 while (
'/' == *inPtr)
341 {
342 inPtr++;
343 }
344 }
345 outPtr++;
346 }
347 *outPtr=
0;
348 strcpy(pathname, buf);
349
350
351 inPtr = pathname;
352 outPtr = buf;
353
354 copyThruSlash(&outPtr, &inPtr);
355 while (inPtr !=
NULL) {
356
357 if (compareThruSlash(inPtr,
"../")) {
358 *outPtr =
0;
359
360
361
362
363
364 #ifdef S_ISLNK
365 if(outPtr-
1 == buf || (lstat(buf, &statbuf) ==
0 &&
366 S_ISLNK(statbuf.st_mode))) {
367 copyThruSlash(&outPtr, &inPtr);
368 }
else
369 #endif
370 {
371
372 outPtr = prevSlash(outPtr);
373 inPtr = nextSlash(inPtr);
374 }
375 }
else if (compareThruSlash(inPtr,
"./")) {
376
377 inPtr = nextSlash(inPtr);
378 }
else {
379
380 copyThruSlash(&outPtr, &inPtr);
381 }
382 }
383
384 if (strlen(buf)>
MAXPATHLEN) {
385 fprintf(stderr,
"nedit: CompressPathname(): file name too long %s\n",
386 pathname);
387 free(buf);
388 return 1;
389 }
390 else {
391 strcpy(pathname, buf);
392 free(buf);
393 return 0;
394 }
395 }
396
397 static char
398 *nextSlash(
char *ptr)
399 {
400 for(; *ptr!=
'/'; ptr++) {
401 if (*ptr ==
'\0')
402 return NULL;
403 }
404 return ptr +
1;
405 }
406
407 static char
408 *prevSlash(
char *ptr)
409 {
410 for(ptr -=
2; *ptr!=
'/'; ptr--);
411 return ptr +
1;
412 }
413
414 static int
415 compareThruSlash(
const char *string1,
const char *string2)
416 {
417 while (
TRUE) {
418 if (*string1 != *string2)
419 return FALSE;
420 if (*string1 ==
'\0' || *string1==
'/')
421 return TRUE;
422 string1++;
423 string2++;
424 }
425 }
426
427 static void
428 copyThruSlash(
char **toString,
char **fromString)
429 {
430 char *to = *toString;
431 char *from = *fromString;
432
433 while (
TRUE) {
434 *to = *from;
435 if (*from ==
'\0') {
436 *fromString =
NULL;
437 return;
438 }
439 if (*from==
'/') {
440 *toString = to +
1;
441 *fromString = from +
1;
442 return;
443 }
444 from++;
445 to++;
446 }
447 }
448
449 #else
450
451
452
453
454
455
456
457
458 int NormalizePathname(
char *pathname)
459 {
460 return 0;
461 }
462
463
464
465
466 int CompressPathname(
char *pathname)
467 {
468 return 0;
469 }
470
471
472
473
474
475
476
477 int ResolvePath(
const char * pathIn,
char * pathResolved)
478 {
479 if (strlen(pathIn) <
MAXPATHLEN) {
480 strcpy(pathResolved, pathIn);
481 return TRUE;
482 }
else {
483 return FALSE;
484 }
485 }
486
487 #endif
488
489
490
491
492 const char
493 *GetTrailingPathComponents(
const char* path,
494 int noOfComponents)
495 {
496
497 const char* ptr = path + strlen(path);
498 int count =
0;
499
500 while (--ptr > path) {
501 if (*ptr ==
'/') {
502 if (count++ == noOfComponents) {
503 break;
504 }
505 }
506 }
507 return(ptr);
508 }
509
510
511
512
513
514
515
516
517
518 int FormatOfFile(
const char *fileString)
519 {
520 const char *p;
521 int nNewlines =
0, nReturns =
0;
522
523 for (p=fileString; *p!=
'\0' && p < fileString +
FORMAT_SAMPLE_CHARS; p++) {
524 if (*p ==
'\n') {
525 nNewlines++;
526 if (p == fileString || *(p-
1) !=
'\r')
527 return UNIX_FILE_FORMAT;
528 if (nNewlines >=
FORMAT_SAMPLE_LINES)
529 return DOS_FILE_FORMAT;
530 }
else if (*p ==
'\r')
531 nReturns++;
532 }
533 if (nNewlines >
0)
534 return DOS_FILE_FORMAT;
535 if (nReturns >
0)
536 return MAC_FILE_FORMAT;
537 return UNIX_FILE_FORMAT;
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551 void ConvertFromDosFileString(
char *fileString,
int *length,
552 char* pendingCR)
553 {
554 char *outPtr = fileString;
555 char *inPtr = fileString;
556 if (pendingCR) *pendingCR =
0;
557 while (inPtr < fileString + *length) {
558 if (*inPtr ==
'\r') {
559 if (inPtr < fileString + *length -
1) {
560 if (*(inPtr +
1) ==
'\n')
561 inPtr++;
562 }
else {
563 if (pendingCR) {
564 *pendingCR = *inPtr;
565 break;
566 }
567 }
568 }
569 *outPtr++ = *inPtr++;
570 }
571 *outPtr =
'\0';
572 *length = outPtr - fileString;
573 }
574 void ConvertFromMacFileString(
char *fileString,
int length)
575 {
576 char *inPtr = fileString;
577 while (inPtr < fileString + length) {
578 if (*inPtr ==
'\r' )
579 *inPtr =
'\n';
580 inPtr++;
581 }
582 }
583
584
585
586
587
588
589
590
591
592
593
594
595 int ConvertToDosFileString(
char **fileString,
int *length)
596 {
597 char *outPtr, *outString;
598 char *inPtr = *fileString;
599 int inLength = *length;
600 int outLength =
0;
601
602
603 while (inPtr < *fileString + inLength) {
604 if (*inPtr ==
'\n')
605 outLength++;
606 inPtr++;
607 outLength++;
608 }
609
610
611 outString = (
char*)malloc(outLength +
1);
612 if (outString ==
NULL)
613 return FALSE;
614
615
616 inPtr = *fileString;
617 outPtr = outString;
618 while (inPtr < *fileString + inLength) {
619 if (*inPtr ==
'\n')
620 *outPtr++ =
'\r';
621 *outPtr++ = *inPtr++;
622 }
623 *outPtr =
'\0';
624 NEditFree(*fileString);
625 *fileString = outString;
626 *length = outLength;
627 return TRUE;
628 }
629
630
631
632
633
634 void ConvertToMacFileString(
char *fileString,
int length)
635 {
636 char *inPtr = fileString;
637
638 while (inPtr < fileString + length) {
639 if (*inPtr ==
'\n' )
640 *inPtr =
'\r';
641 inPtr++;
642 }
643 }
644
645
646
647
648
649
650
651 char *ReadAnyTextFile(
const char *fileName,
int forceNL)
652 {
653 struct stat statbuf;
654 FILE *fp;
655 int fileLen, readLen;
656 char *fileString;
657 int format;
658
659
660 if ((fp = fopen(fileName,
"r")) ==
NULL) {
661 return NULL;
662 }
663 if (fstat(fileno(fp), &statbuf) !=
0) {
664 fclose(fp);
665 return NULL;
666 }
667 fileLen = statbuf.st_size;
668
669
670
671 fileString = (
char*)NEditMalloc(fileLen +
2);
672 readLen = fread(fileString,
sizeof(
char), fileLen, fp);
673 if (ferror(fp)) {
674 NEditFree(fileString);
675 fclose(fp);
676 return NULL;
677 }
678 fclose(fp);
679 fileString[readLen] =
0;
680
681
682 format = FormatOfFile(fileString);
683 if (format ==
DOS_FILE_FORMAT){
684 char pendingCR;
685 ConvertFromDosFileString(fileString, &readLen, &pendingCR);
686 }
else if (format ==
MAC_FILE_FORMAT){
687 ConvertFromMacFileString(fileString, readLen);
688 }
689
690
691 if (forceNL && fileString[readLen -
1] !=
'\n') {
692 fileString[readLen] =
'\n';
693 fileString[readLen +
1] =
'\0';
694 }
695
696 return fileString;
697 }
698