1/* addext.c -- add an extension to a file name
2   Copyright (C) 1990, 1997, 1998, 1999 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; see the file COPYING.
16   If not, write to the Free Software Foundation,
17   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19/* Written by David MacKenzie <djm@gnu.ai.mit.edu> and Paul Eggert */
20
21#if HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#ifndef HAVE_DOS_FILE_NAMES
26# define HAVE_DOS_FILE_NAMES 0
27#endif
28#ifndef HAVE_LONG_FILE_NAMES
29# define HAVE_LONG_FILE_NAMES 0
30#endif
31
32#include <backupfile.h>
33
34#if HAVE_LIMITS_H
35# include <limits.h>
36#endif
37#ifndef _POSIX_NAME_MAX
38# define _POSIX_NAME_MAX 14
39#endif
40
41#include <sys/types.h>
42#if HAVE_STRING_H
43# include <string.h>
44#else
45# include <strings.h>
46#endif
47
48#if HAVE_UNISTD_H
49# include <unistd.h>
50#endif
51
52char *base_name PARAMS ((char const *));
53
54/* Append to FILENAME the extension EXT, unless the result would be too long,
55   in which case just append the character E.  */
56
57void
58addext (char *filename, char const *ext, int e)
59{
60  char *s = base_name (filename);
61  size_t slen = strlen (s), extlen = strlen (ext);
62  long slen_max = -1;
63
64#if HAVE_PATHCONF && defined _PC_NAME_MAX
65  if (slen + extlen <= _POSIX_NAME_MAX && ! HAVE_DOS_FILE_NAMES)
66    /* The file name is so short there's no need to call pathconf.  */
67    slen_max = _POSIX_NAME_MAX;
68  else if (s == filename)
69    slen_max = pathconf (".", _PC_NAME_MAX);
70  else
71    {
72      char c = *s;
73      *s = 0;
74      slen_max = pathconf (filename, _PC_NAME_MAX);
75      *s = c;
76    }
77#endif
78  if (slen_max < 0)
79    slen_max = HAVE_LONG_FILE_NAMES ? 255 : 14;
80
81  if (HAVE_DOS_FILE_NAMES && slen_max <= 12)
82    {
83      /* Live within DOS's 8.3 limit.  */
84      char *dot = strchr (s, '.');
85      if (dot)
86	{
87	  slen -= dot + 1 - s;
88	  s = dot + 1;
89	  slen_max = 3;
90	}
91      else
92	slen_max = 8;
93      extlen = 9; /* Don't use EXT.  */
94    }
95
96  if (slen + extlen <= slen_max)
97    strcpy (s + slen, ext);
98  else
99    {
100      if (slen_max <= slen)
101	slen = slen_max - 1;
102      s[slen] = e;
103      s[slen + 1] = 0;
104    }
105}
106