(new_volume): Initialize current_block
[debian/tar] / src / port.c
1 /* Supporting routines which may sometimes be missing.
2    Copyright (C) 1988, 1992 Free Software Foundation
3
4 This file is part of GNU Tar.
5
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <signal.h>
23 #include <errno.h>
24 #ifndef STDC_HEADERS
25 extern int errno;
26 #endif
27
28 #ifdef BSD42
29 #include <sys/file.h>
30 #else
31 #ifndef V7
32 #include <fcntl.h>
33 #endif
34 #endif
35
36 #include "tar.h"
37 #include "port.h"
38
39 extern long baserec;
40
41 /* All machine-dependent #ifdefs should appear here, instead of
42    being scattered through the file.  For UN*X systems, it is better to
43    figure out what is needed in the configure script, for most of the
44    features. */
45
46 #ifdef __MSDOS__
47 char TTY_NAME[] = "con";
48 #define HAVE_STRSTR
49 #define HAVE_RENAME
50 #define HAVE_MKDIR
51 #else
52 char TTY_NAME[] = "/dev/tty";
53 #endif
54
55 /* End of system-dependent #ifdefs */
56
57
58 #ifndef HAVE_VALLOC
59 /*
60  * valloc() does a malloc() on a page boundary.  On some systems,
61  * this can make large block I/O more efficient.
62  */
63 char *
64 valloc (size)
65      unsigned size;
66 {
67   return (malloc (size));
68 }
69
70 #endif /* !HAVE_VALLOC */
71
72 #ifndef HAVE_MKDIR
73 /*
74  * Written by Robert Rother, Mariah Corporation, August 1985.
75  *
76  * If you want it, it's yours.  All I ask in return is that if you
77  * figure out how to do this in a Bourne Shell script you send me
78  * a copy.
79  *                                      sdcsvax!rmr or rmr@uscd
80  *
81  * Severely hacked over by John Gilmore to make a 4.2BSD compatible
82  * subroutine.  11Mar86; hoptoad!gnu
83  *
84  * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
85  * subroutine didn't return EEXIST.  It does now.
86  */
87
88 /*
89  * Make a directory.
90  */
91 int
92 mkdir (dpath, dmode)
93      char *dpath;
94      int dmode;
95 {
96   int cpid, status;
97   struct stat statbuf;
98
99   if (stat (dpath, &statbuf) == 0)
100     {
101       errno = EEXIST;           /* Stat worked, so it already exists */
102       return -1;
103     }
104
105   /* If stat fails for a reason other than non-existence, return error */
106   if (errno != ENOENT)
107     return -1;
108
109   switch (cpid = fork ())
110     {
111
112     case -1:                    /* Error in fork() */
113       return (-1);              /* Errno is set already */
114
115     case 0:                     /* Child process */
116       /*
117                  * Cheap hack to set mode of new directory.  Since this
118                  * child process is going away anyway, we zap its umask.
119                  * FIXME, this won't suffice to set SUID, SGID, etc. on this
120                  * directory.  Does anybody care?
121                  */
122       status = umask (0);       /* Get current umask */
123       status = umask (status | (0777 & ~dmode));        /* Set for mkdir */
124       execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
125       _exit (-1);               /* Can't exec /bin/mkdir */
126
127     default:                    /* Parent process */
128       while (cpid != wait (&status));   /* Wait for kid to finish */
129     }
130
131   if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
132     {
133       errno = EIO;              /* We don't know why, but */
134       return -1;                /* /bin/mkdir failed */
135     }
136
137   return 0;
138 }
139
140 int
141 rmdir (dpath)
142      char *dpath;
143 {
144   int cpid, status;
145   struct stat statbuf;
146
147   if (stat (dpath, &statbuf) != 0)
148     {
149       /* Stat just set errno.  We don't have to */
150       return -1;
151     }
152
153   switch (cpid = fork ())
154     {
155
156     case -1:                    /* Error in fork() */
157       return (-1);              /* Errno is set already */
158
159     case 0:                     /* Child process */
160       execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
161       _exit (-1);               /* Can't exec /bin/mkdir */
162
163     default:                    /* Parent process */
164       while (cpid != wait (&status));   /* Wait for kid to finish */
165     }
166
167   if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
168     {
169       errno = EIO;              /* We don't know why, but */
170       return -1;                /* /bin/mkdir failed */
171     }
172
173   return 0;
174 }
175
176 #endif /* !HAVE_MKDIR */
177
178 #ifndef HAVE_RENAME
179 /* Rename file FROM to file TO.
180    Return 0 if successful, -1 if not. */
181
182 int
183 rename (from, to)
184      char *from;
185      char *to;
186 {
187   struct stat from_stats;
188
189   if (stat (from, &from_stats))
190     return -1;
191
192   if (unlink (to) && errno != ENOENT)
193     return -1;
194
195   if (link (from, to))
196     return -1;
197
198   if (unlink (from) && errno != ENOENT)
199     {
200       unlink (to);
201       return -1;
202     }
203
204   return 0;
205 }
206
207 #endif /* !HAVE_RENAME */
208
209 #ifdef minix
210 /* Minix has bcopy but not bzero, and no memset.  Thanks, Andy. */
211 void
212 bzero (s1, n)
213      register char *s1;
214      register int n;
215 {
216   while (n--)
217     *s1++ = '\0';
218 }
219
220 /* It also has no bcmp() */
221 int
222 bcmp (s1, s2, n)
223      register char *s1, *s2;
224      register int n;
225 {
226   for (; n--; ++s1, ++s2)
227     {
228       if (*s1 != *s2)
229         return *s1 - *s2;
230     }
231   return 0;
232 }
233
234 /*
235  * Groan, Minix doesn't have execlp either!
236  *
237  * execlp(file,arg0,arg1...argn,(char *)NULL)
238  * exec a program, automatically searching for the program through
239  * all the directories on the PATH.
240  *
241  * This version is naive about variable argument lists, it assumes
242  * a straightforward C calling sequence.  If your system has odd stacks
243  * *and* doesn't have execlp, YOU get to fix it.
244  */
245 int
246 execlp (filename, arg0)
247      char *filename, *arg0;
248 {
249   register char *p, *path;
250   register char *fnbuffer;
251   char **argstart = &arg0;
252   struct stat statbuf;
253   extern char **environ;
254
255   if ((p = getenv ("PATH")) == NULL)
256     {
257       /* couldn't find path variable -- try to exec given filename */
258       return execve (filename, argstart, environ);
259     }
260
261   /*
262          * make a place to build the filename.  We malloc larger than we
263          * need, but we know it will fit in this.
264          */
265   fnbuffer = malloc (strlen (p) + 1 + strlen (filename));
266   if (fnbuffer == NULL)
267     {
268       errno = ENOMEM;
269       return -1;
270     }
271
272   /*
273          * try each component of the path to see if the file's there
274          * and executable.
275          */
276   for (path = p; path; path = p)
277     {
278       /* construct full path name to try */
279       if ((p = index (path, ':')) == NULL)
280         {
281           strcpy (fnbuffer, path);
282         }
283       else
284         {
285           strncpy (fnbuffer, path, p - path);
286           fnbuffer[p - path] = '\0';
287           p++;                  /* Skip : for next time */
288         }
289       if (strlen (fnbuffer) != 0)
290         strcat (fnbuffer, "/");
291       strcat (fnbuffer, filename);
292
293       /* check to see if file is there and is a normal file */
294       if (stat (fnbuffer, &statbuf) < 0)
295         {
296           if (errno == ENOENT)
297             continue;           /* file not there,keep on looking */
298           else
299             goto fail;          /* failed for some reason, return */
300         }
301       if (!S_ISREG (statbuf.st_mode))
302         continue;
303
304       if (execve (fnbuffer, argstart, environ) < 0
305           && errno != ENOENT
306           && errno != ENOEXEC)
307         {
308           /* failed, for some other reason besides "file
309                          * not found" or "not a.out format"
310                          */
311           goto fail;
312         }
313
314       /*
315                  * If we got error ENOEXEC, the file is executable but is
316                  * not an object file.  Try to execute it as a shell script,
317                  * returning error if we can't execute /bin/sh.
318                  *
319                  * FIXME, this code is broken in several ways.  Shell
320                  * scripts should not in general be executed by the user's
321                  * SHELL variable program.  On more mature systems, the
322                  * script can specify with #!/bin/whatever.  Also, this
323                  * code clobbers argstart[-1] if the exec of the shell
324                  * fails.
325                  */
326       if (errno == ENOEXEC)
327         {
328           char *shell;
329
330           /* Try to execute command "sh arg0 arg1 ..." */
331           if ((shell = getenv ("SHELL")) == NULL)
332             shell = "/bin/sh";
333           argstart[-1] = shell;
334           argstart[0] = fnbuffer;
335           execve (shell, &argstart[-1], environ);
336           goto fail;            /* Exec didn't work */
337         }
338
339       /*
340                  * If we succeeded, the execve() doesn't return, so we
341                  * can only be here is if the file hasn't been found yet.
342                  * Try the next place on the path.
343                  */
344     }
345
346   /* all attempts failed to locate the file.  Give up. */
347   errno = ENOENT;
348
349 fail:
350   free (fnbuffer);
351   return -1;
352 }
353
354 #endif /* minix */
355
356
357 #ifdef EMUL_OPEN3
358 #include "open3.h"
359 /*
360  * open3 -- routine to emulate the 3-argument open system
361  * call that is present in most modern Unix systems.
362  * This version attempts to support all the flag bits except for O_NDELAY
363  * and O_APPEND, which are silently ignored.  The emulation is not as efficient
364  * as the real thing (at worst, 4 system calls instead of one), but there's
365  * not much I can do about that.
366  *
367  * Written 6/10/87 by rmtodd@uokmax
368  *
369  * open3(path, flag, mode)
370  * Attempts to open the file specified by
371  * the given pathname.  The following flag bits (#defined in tar.h)
372  * specify options to the routine:
373  *      O_RDONLY        file open for read only
374  *      O_WRONLY        file open for write only
375  *      O_RDWR          file open for both read & write
376  * (Needless to say, you should only specify one of the above).
377  *      O_CREAT         file is created with specified mode if it needs to be.
378  *      O_TRUNC         if file exists, it is truncated to 0 bytes
379  *      O_EXCL          used with O_CREAT--routine returns error if file exists
380  * Function returns file descriptor if successful, -1 and errno if not.
381  */
382
383 /*
384  * array to give arguments to access for various modes
385  * FIXME, this table depends on the specific integer values of O_XXX,
386  * and also contains integers (args to 'access') that should be #define's.
387  */
388 static int modes[] =
389 {
390   04,                           /* O_RDONLY */
391   02,                           /* O_WRONLY */
392   06,                           /* O_RDWR */
393   06,                           /* invalid but we'd better cope -- O_WRONLY+O_RDWR */
394 };
395
396 /* Shut off the automatic emulation of open(), we'll need it. */
397 #undef open
398
399 int
400 open3 (path, flags, mode)
401      char *path;
402      int flags, mode;
403 {
404   int exists = 1;
405   int call_creat = 0;
406   int fd;
407   /*
408          * We actually do the work by calling the open() or creat() system
409          * call, depending on the flags.  Call_creat is true if we will use
410          * creat(), false if we will use open().
411          */
412
413   /*
414          * See if the file exists and is accessible in the requested mode.
415          *
416          * Strictly speaking we shouldn't be using access, since access checks
417          * against real uid, and the open call should check against euid.
418          * Most cases real uid == euid, so it won't matter.   FIXME.
419          * FIXME, the construction "flags & 3" and the modes table depends
420          * on the specific integer values of the O_XXX #define's.  Foo!
421          */
422   if (access (path, modes[flags & 3]) < 0)
423     {
424       if (errno == ENOENT)
425         {
426           /* the file does not exist */
427           exists = 0;
428         }
429       else
430         {
431           /* probably permission violation */
432           if (flags & O_EXCL)
433             {
434               /* Oops, the file exists, we didn't want it. */
435               /* No matter what the error, claim EEXIST. */
436               errno = EEXIST;
437             }
438           return -1;
439         }
440     }
441
442   /* if we have the O_CREAT bit set, check for O_EXCL */
443   if (flags & O_CREAT)
444     {
445       if ((flags & O_EXCL) && exists)
446         {
447           /* Oops, the file exists and we didn't want it to. */
448           errno = EEXIST;
449           return -1;
450         }
451       /*
452                  * If the file doesn't exist, be sure to call creat() so that
453                  * it will be created with the proper mode.
454                  */
455       if (!exists)
456         call_creat = 1;
457     }
458   else
459     {
460       /* If O_CREAT isn't set and the file doesn't exist, error. */
461       if (!exists)
462         {
463           errno = ENOENT;
464           return -1;
465         }
466     }
467
468   /*
469          * If the O_TRUNC flag is set and the file exists, we want to call
470          * creat() anyway, since creat() guarantees that the file will be
471          * truncated and open()-for-writing doesn't.
472          * (If the file doesn't exist, we're calling creat() anyway and the
473          * file will be created with zero length.)
474          */
475   if ((flags & O_TRUNC) && exists)
476     call_creat = 1;
477   /* actually do the call */
478   if (call_creat)
479     {
480       /*
481                  * call creat.  May have to close and reopen the file if we
482                  * want O_RDONLY or O_RDWR access -- creat() only gives
483                  * O_WRONLY.
484                  */
485       fd = creat (path, mode);
486       if (fd < 0 || (flags & O_WRONLY))
487         return fd;
488       if (close (fd) < 0)
489         return -1;
490       /* Fall out to reopen the file we've created */
491     }
492
493   /*
494          * calling old open, we strip most of the new flags just in case.
495          */
496   return open (path, flags & (O_RDONLY | O_WRONLY | O_RDWR | O_BINARY));
497 }
498
499 #endif /* EMUL_OPEN3 */
500
501 #ifndef HAVE_MKNOD
502 #ifdef __MSDOS__
503 typedef int dev_t;
504 #endif
505 /* Fake mknod by complaining */
506 int
507 mknod (path, mode, dev)
508      char *path;
509      unsigned short mode;
510      dev_t dev;
511 {
512   int fd;
513
514   errno = ENXIO;                /* No such device or address */
515   return -1;                    /* Just give an error */
516 }
517
518 /* Fake links by copying */
519 int
520 link (path1, path2)
521      char *path1;
522      char *path2;
523 {
524   char buf[256];
525   int ifd, ofd;
526   int nrbytes;
527   int nwbytes;
528
529   fprintf (stderr, "%s: %s: cannot link to %s, copying instead\n",
530            tar, path1, path2);
531   if ((ifd = open (path1, O_RDONLY | O_BINARY)) < 0)
532     return -1;
533   if ((ofd = creat (path2, 0666)) < 0)
534     return -1;
535   setmode (ofd, O_BINARY);
536   while ((nrbytes = read (ifd, buf, sizeof (buf))) > 0)
537     {
538       if ((nwbytes = write (ofd, buf, nrbytes)) != nrbytes)
539         {
540           nrbytes = -1;
541           break;
542         }
543     }
544   /* Note use of "|" rather than "||" below: we want to close
545          * the files even if an error occurs.
546          */
547   if ((nrbytes < 0) | (0 != close (ifd)) | (0 != close (ofd)))
548     {
549       unlink (path2);
550       return -1;
551     }
552   return 0;
553 }
554
555 /* everyone owns everything on MS-DOS (or is it no one owns anything?) */
556 int
557 chown (path, uid, gid)
558      char *path;
559      int uid;
560      int gid;
561 {
562   return 0;
563 }
564
565 int
566 geteuid ()
567 {
568   return 0;
569 }
570
571 #endif /* !HAVE_MKNOD */
572
573 #ifdef __TURBOC__
574 #include <time.h>
575 #include <fcntl.h>
576 #include <io.h>
577
578 struct utimbuf
579 {
580   time_t actime;                /* Access time. */
581   time_t modtime;               /* Modification time. */
582 };
583
584 int
585 utime (char *filename, struct utimbuf *utb)
586 {
587   struct tm *tm;
588   struct ftime filetime;
589   time_t when;
590   int fd;
591   int status;
592
593   if (utb == 0)
594     when = time (0);
595   else
596     when = utb->modtime;
597
598   fd = _open (filename, O_RDWR);
599   if (fd == -1)
600     return -1;
601
602   tm = localtime (&when);
603   if (tm->tm_year < 80)
604     filetime.ft_year = 0;
605   else
606     filetime.ft_year = tm->tm_year - 80;
607   filetime.ft_month = tm->tm_mon + 1;
608   filetime.ft_day = tm->tm_mday;
609   if (tm->tm_hour < 0)
610     filetime.ft_hour = 0;
611   else
612     filetime.ft_hour = tm->tm_hour;
613   filetime.ft_min = tm->tm_min;
614   filetime.ft_tsec = tm->tm_sec / 2;
615
616   status = setftime (fd, &filetime);
617   _close (fd);
618   return status;
619 }
620
621 #endif /* __TURBOC__ */
622
623 /* Stash argv[0] here so panic will know what the program is called */
624 char *myname = 0;
625
626 void
627 panic (s)
628      char *s;
629 {
630   if (myname)
631     fprintf (stderr, "%s:", myname);
632   fprintf (stderr, s);
633   putc ('\n', stderr);
634   exit (12);
635 }
636
637
638 PTR
639 ck_malloc (size)
640      size_t size;
641 {
642   PTR ret;
643
644   if (!size)
645     size++;
646   ret = malloc (size);
647   if (ret == 0)
648     panic ("Couldn't allocate memory");
649   return ret;
650 }
651
652 /* Used by alloca.c and bison.simple. */
653 char *
654 xmalloc (size)
655      size_t size;
656 {
657   return (char *) ck_malloc (size);
658 }
659
660 PTR
661 ck_realloc (ptr, size)
662      PTR ptr;
663      size_t size;
664 {
665   PTR ret;
666
667   if (!ptr)
668     ret = ck_malloc (size);
669   else
670     ret = realloc (ptr, size);
671   if (ret == 0)
672     panic ("Couldn't re-allocate memory");
673   return ret;
674 }
675
676 /* Implement a variable sized buffer of 'stuff'.  We don't know what it is,
677    nor do we care, as long as it doesn't mind being aligned on a char boundry.
678  */
679
680 struct buffer
681   {
682     int allocated;
683     int length;
684     char *b;
685   };
686
687 #define MIN_ALLOCATE 50
688
689 char *
690 init_buffer ()
691 {
692   struct buffer *b;
693
694   b = (struct buffer *) ck_malloc (sizeof (struct buffer));
695   b->allocated = MIN_ALLOCATE;
696   b->b = (char *) ck_malloc (MIN_ALLOCATE);
697   b->length = 0;
698   return (char *) b;
699 }
700
701 void
702 flush_buffer (bb)
703      char *bb;
704 {
705   struct buffer *b;
706
707   b = (struct buffer *) bb;
708   free (b->b);
709   b->b = 0;
710   b->allocated = 0;
711   b->length = 0;
712   free ((void *) b);
713 }
714
715 void
716 add_buffer (bb, p, n)
717      char *bb;
718      char *p;
719      int n;
720 {
721   struct buffer *b;
722
723   b = (struct buffer *) bb;
724   if (b->length + n > b->allocated)
725     {
726       b->allocated = b->length + n + MIN_ALLOCATE;
727       b->b = (char *) ck_realloc (b->b, b->allocated);
728     }
729   bcopy (p, b->b + b->length, n);
730   b->length += n;
731 }
732
733 char *
734 get_buffer (bb)
735      char *bb;
736 {
737   struct buffer *b;
738
739   b = (struct buffer *) bb;
740   return b->b;
741 }
742
743 char *
744 merge_sort (list, n, off, cmp)
745      char *list;
746      int (*cmp) ();
747      unsigned n;
748      int off;
749 {
750   char *ret;
751
752   char *alist, *blist;
753   unsigned alength, blength;
754
755   char *tptr;
756   int tmp;
757   char **prev;
758 #define NEXTOF(ptr)     (* ((char **)(((char *)(ptr))+off) ) )
759   if (n == 1)
760     return list;
761   if (n == 2)
762     {
763       if ((*cmp) (list, NEXTOF (list)) > 0)
764         {
765           ret = NEXTOF (list);
766           NEXTOF (ret) = list;
767           NEXTOF (list) = 0;
768           return ret;
769         }
770       return list;
771     }
772   alist = list;
773   alength = (n + 1) / 2;
774   blength = n / 2;
775   for (tptr = list, tmp = (n - 1) / 2; tmp; tptr = NEXTOF (tptr), tmp--)
776     ;
777   blist = NEXTOF (tptr);
778   NEXTOF (tptr) = 0;
779
780   alist = merge_sort (alist, alength, off, cmp);
781   blist = merge_sort (blist, blength, off, cmp);
782   prev = &ret;
783   for (; alist && blist;)
784     {
785       if ((*cmp) (alist, blist) < 0)
786         {
787           tptr = NEXTOF (alist);
788           *prev = alist;
789           prev = &(NEXTOF (alist));
790           alist = tptr;
791         }
792       else
793         {
794           tptr = NEXTOF (blist);
795           *prev = blist;
796           prev = &(NEXTOF (blist));
797           blist = tptr;
798         }
799     }
800   if (alist)
801     *prev = alist;
802   else
803     *prev = blist;
804
805   return ret;
806 }
807
808 void
809 ck_close (fd)
810      int fd;
811 {
812   if (close (fd) < 0)
813     {
814       msg_perror ("can't close a file #%d", fd);
815       exit (EX_SYSTEM);
816     }
817 }
818
819 #include <ctype.h>
820
821 /* Quote_copy_string is like quote_string, but instead of modifying the
822    string in place, it malloc-s a copy  of the string, and returns that.
823    If the string does not have to be quoted, it returns the NULL string.
824    The allocated copy can, of course, be freed with free() after the
825    caller is done with it.
826  */
827 char *
828 quote_copy_string (string)
829      char *string;
830 {
831   char *from_here;
832   char *to_there = 0;
833   char *copy_buf = 0;
834   int c;
835   int copying = 0;
836
837   from_here = string;
838   while (*from_here)
839     {
840       c = *from_here++;
841       if (c == '\\')
842         {
843           if (!copying)
844             {
845               int n;
846
847               n = (from_here - string) - 1;
848               copying++;
849               copy_buf = (char *) malloc (n + 5 + strlen (from_here) * 4);
850               if (!copy_buf)
851                 return 0;
852               bcopy (string, copy_buf, n);
853               to_there = copy_buf + n;
854             }
855           *to_there++ = '\\';
856           *to_there++ = '\\';
857         }
858       else if (isprint (c))
859         {
860           if (copying)
861             *to_there++ = c;
862         }
863       else
864         {
865           if (!copying)
866             {
867               int n;
868
869               n = (from_here - string) - 1;
870               copying++;
871               copy_buf = (char *) malloc (n + 5 + strlen (from_here) * 4);
872               if (!copy_buf)
873                 return 0;
874               bcopy (string, copy_buf, n);
875               to_there = copy_buf + n;
876             }
877           *to_there++ = '\\';
878           if (c == '\n')
879             *to_there++ = 'n';
880           else if (c == '\t')
881             *to_there++ = 't';
882           else if (c == '\f')
883             *to_there++ = 'f';
884           else if (c == '\b')
885             *to_there++ = 'b';
886           else if (c == '\r')
887             *to_there++ = 'r';
888           else if (c == '\177')
889             *to_there++ = '?';
890           else
891             {
892               to_there[0] = (c >> 6) + '0';
893               to_there[1] = ((c >> 3) & 07) + '0';
894               to_there[2] = (c & 07) + '0';
895               to_there += 3;
896             }
897         }
898     }
899   if (copying)
900     {
901       *to_there = '\0';
902       return copy_buf;
903     }
904   return (char *) 0;
905 }
906
907
908 /* Un_quote_string takes a quoted c-string (like those produced by
909    quote_string or quote_copy_string and turns it back into the
910    un-quoted original.  This is done in place.
911  */
912
913 /* There is no un-quote-copy-string.  Write it yourself */
914
915 char *
916 un_quote_string (string)
917      char *string;
918 {
919   char *ret;
920   char *from_here;
921   char *to_there;
922   int tmp;
923
924   ret = string;
925   to_there = string;
926   from_here = string;
927   while (*from_here)
928     {
929       if (*from_here != '\\')
930         {
931           if (from_here != to_there)
932             *to_there++ = *from_here++;
933           else
934             from_here++, to_there++;
935           continue;
936         }
937       switch (*++from_here)
938         {
939         case '\\':
940           *to_there++ = *from_here++;
941           break;
942         case 'n':
943           *to_there++ = '\n';
944           from_here++;
945           break;
946         case 't':
947           *to_there++ = '\t';
948           from_here++;
949           break;
950         case 'f':
951           *to_there++ = '\f';
952           from_here++;
953           break;
954         case 'b':
955           *to_there++ = '\b';
956           from_here++;
957           break;
958         case 'r':
959           *to_there++ = '\r';
960           from_here++;
961           break;
962         case '?':
963           *to_there++ = 0177;
964           from_here++;
965           break;
966         case '0':
967         case '1':
968         case '2':
969         case '3':
970         case '4':
971         case '5':
972         case '6':
973         case '7':
974           tmp = *from_here - '0';
975           from_here++;
976           if (*from_here < '0' || *from_here > '7')
977             {
978               *to_there++ = tmp;
979               break;
980             }
981           tmp = tmp * 8 + *from_here - '0';
982           from_here++;
983           if (*from_here < '0' || *from_here > '7')
984             {
985               *to_there++ = tmp;
986               break;
987             }
988           tmp = tmp * 8 + *from_here - '0';
989           from_here++;
990           *to_there = tmp;
991           break;
992         default:
993           ret = 0;
994           *to_there++ = '\\';
995           *to_there++ = *from_here++;
996           break;
997         }
998     }
999   if (*to_there)
1000     *to_there++ = '\0';
1001   return ret;
1002 }
1003
1004 #ifndef __MSDOS__
1005 void 
1006 ck_pipe (pipes)
1007      int *pipes;
1008 {
1009   if (pipe (pipes) < 0)
1010     {
1011       msg_perror ("can't open a pipe");
1012       exit (EX_SYSTEM);
1013     }
1014 }
1015 #endif /* !__MSDOS__ */
1016
1017 #ifndef HAVE_STRSTR
1018 /*
1019  * strstr - find first occurrence of wanted in s
1020  */
1021
1022 char *                          /* found string, or NULL if none */
1023 strstr (s, wanted)
1024      char *s;
1025      char *wanted;
1026 {
1027   register char *scan;
1028   register size_t len;
1029   register char firstc;
1030
1031   if (*wanted == '\0')
1032     return (char *) 0;
1033   /*
1034          * The odd placement of the two tests is so "" is findable.
1035          * Also, we inline the first char for speed.
1036          * The ++ on scan has been moved down for optimization.
1037          */
1038   firstc = *wanted;
1039   len = strlen (wanted);
1040   for (scan = s; *scan != firstc || strncmp (scan, wanted, len) != 0;)
1041     if (*scan++ == '\0')
1042       return (char *) 0;
1043   return scan;
1044 }
1045
1046 #endif /* !HAVE_STRSTR */
1047
1048 #ifndef HAVE_FTRUNCATE
1049
1050 #ifdef F_CHSIZE
1051 int
1052 ftruncate (fd, length)
1053      int fd;
1054      off_t length;
1055 {
1056   return fcntl (fd, F_CHSIZE, length);
1057 }
1058
1059 #else /* !F_CHSIZE */
1060 #ifdef F_FREESP
1061 /* code courtesy of William Kucharski, kucharsk@Solbourne.com */
1062
1063 int
1064 ftruncate (fd, length)
1065      int fd;                    /* file descriptor */
1066      off_t length;              /* length to set file to */
1067 {
1068   struct flock fl;
1069
1070   fl.l_whence = 0;
1071   fl.l_len = 0;
1072   fl.l_start = length;
1073   fl.l_type = F_WRLCK;          /* write lock on file space */
1074
1075   /*
1076          * This relies on the UNDOCUMENTED F_FREESP argument to
1077          * fcntl(2), which truncates the file so that it ends at the
1078          * position indicated by fl.l_start.
1079          *
1080          * Will minor miracles never cease?
1081          */
1082
1083   if (fcntl (fd, F_FREESP, &fl) < 0)
1084     return -1;
1085
1086   return 0;
1087 }
1088
1089 #else /* !F_FREESP */
1090
1091 int
1092 ftruncate (fd, length)
1093      int fd;
1094      off_t length;
1095 {
1096   errno = EIO;
1097   return -1;
1098 }
1099
1100 #endif /* !F_FREESP */
1101 #endif /* !F_CHSIZE */
1102 #endif /* !HAVE_FTRUNCATE */
1103
1104
1105 extern FILE *msg_file;
1106
1107 #if defined (HAVE_VPRINTF) && __STDC__
1108 #include <stdarg.h>
1109
1110 void
1111 msg (char *str,...)
1112 {
1113   va_list args;
1114
1115   va_start (args, str);
1116   fflush (msg_file);
1117   fprintf (stderr, "%s: ", tar);
1118   if (f_sayblock)
1119     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1120   vfprintf (stderr, str, args);
1121   va_end (args);
1122   putc ('\n', stderr);
1123   fflush (stderr);
1124 }
1125
1126 void
1127 msg_perror (char *str,...)
1128 {
1129   va_list args;
1130   int save_e;
1131
1132   save_e = errno;
1133   fflush (msg_file);
1134   fprintf (stderr, "%s: ", tar);
1135   if (f_sayblock)
1136     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1137   va_start (args, str);
1138   vfprintf (stderr, str, args);
1139   va_end (args);
1140   errno = save_e;
1141   perror (" ");
1142   fflush (stderr);
1143 }
1144
1145 #endif /* HAVE_VPRINTF and __STDC__ */
1146
1147 #if defined(HAVE_VPRINTF) && !__STDC__
1148 #include <varargs.h>
1149 void
1150 msg (str, va_alist)
1151      char *str;
1152      va_dcl
1153 {
1154   va_list args;
1155
1156   fflush (msg_file);
1157   fprintf (stderr, "%s: ", tar);
1158   if (f_sayblock)
1159     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1160   va_start (args);
1161   vfprintf (stderr, str, args);
1162   va_end (args);
1163   putc ('\n', stderr);
1164   fflush (stderr);
1165 }
1166
1167 void
1168 msg_perror (str, va_alist)
1169      char *str;
1170      va_dcl
1171 {
1172   va_list args;
1173   int save_e;
1174
1175   save_e = errno;
1176   fflush (msg_file);
1177   fprintf (stderr, "%s: ", tar);
1178   if (f_sayblock)
1179     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1180   va_start (args);
1181   vfprintf (stderr, str, args);
1182   va_end (args);
1183   errno = save_e;
1184   perror (" ");
1185   fflush (stderr);
1186 }
1187
1188 #endif /* HAVE_VPRINTF and not __STDC__ */
1189
1190 #if !defined(HAVE_VPRINTF) && defined(HAVE_DOPRNT)
1191 void
1192 msg (str, args)
1193      char *str;
1194      int args;
1195 {
1196   fflush (msg_file);
1197   fprintf (stderr, "%s: ", tar);
1198   if (f_sayblock)
1199     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1200   _doprnt (str, &args, stderr);
1201   putc ('\n', stderr);
1202   fflush (stderr);
1203 }
1204
1205 void
1206 msg_perror (str, args)
1207      char *str;
1208      int args;
1209 {
1210   int save_e;
1211
1212   save_e = errno;
1213   fflush (msg_file);
1214   fprintf (stderr, "%s: ", tar);
1215   if (f_sayblock)
1216     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1217   _doprnt (str, &args, stderr);
1218   errno = save_e;
1219   perror (" ");
1220   fflush (stderr);
1221 }
1222
1223 #endif /* !HAVE_VPRINTF and HAVE_DOPRNT */
1224
1225 #if !defined(HAVE_VPRINTF) && !defined(HAVE_DOPRNT)
1226 void 
1227 msg (str, a1, a2, a3, a4, a5, a6)
1228      char *str;
1229 {
1230   fflush (msg_file);
1231   fprintf (stderr, "%s: ", tar);
1232   if (f_sayblock)
1233     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1234   fprintf (stderr, str, a1, a2, a3, a4, a5, a6);
1235   putc ('\n', stderr);
1236   fflush (stderr);
1237 }
1238
1239 void
1240 msg_perror (str, a1, a2, a3, a4, a5, a6)
1241      char *str;
1242 {
1243   int save_e;
1244
1245   save_e = errno;
1246   fflush (msg_file);
1247   fprintf (stderr, "%s: ", tar);
1248   if (f_sayblock)
1249     fprintf (stderr, "rec %d: ", baserec + (ar_record - ar_block));
1250   fprintf (stderr, str, a1, a2, a3, a4, a5, a6);
1251   fprintf (stderr, ": ");
1252   errno = save_e;
1253   perror (" ");
1254 }
1255
1256 #endif /* !HAVE_VPRINTF and !HAVE_DOPRNT */