(root)/
texinfo-7.1/
info/
tilde.c
       1  /* tilde.c -- tilde expansion code (~/foo := $HOME/foo).
       2  
       3     Copyright 1988-2023 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17  
      18     Originally written by Brian Fox. */
      19  
      20  #include "info.h"
      21  #include "tilde.h"
      22  
      23  /* Do the work of tilde expansion on FILENAME.  FILENAME starts with a
      24     tilde. */
      25  char *
      26  tilde_expand_word (const char *filename)
      27  {
      28    char *dirname = filename ? xstrdup (filename) : NULL;
      29  
      30    if (dirname && *dirname == '~')
      31      {
      32        char *temp_name;
      33        if (!dirname[1] || IS_SLASH (dirname[1]))
      34          {
      35            /* Prepend $HOME to the rest of the string. */
      36            char *temp_home = getenv ("HOME");
      37  
      38            /* If there is no HOME variable, look up the directory in
      39               the password database. */
      40            if (!temp_home)
      41              {
      42  #ifndef __MINGW32__
      43                struct passwd *entry;
      44  
      45                entry = (struct passwd *) getpwuid (getuid ());
      46                if (entry)
      47                  temp_home = entry->pw_dir;
      48  #else
      49  	      temp_home = ".";
      50  #endif
      51              }
      52  
      53            temp_name = xmalloc (1 + strlen (&dirname[1])
      54                                 + (temp_home ? strlen (temp_home) : 0));
      55            if (temp_home)
      56              strcpy (temp_name, temp_home);
      57            else
      58              temp_name[0] = 0;
      59            strcat (temp_name, &dirname[1]);
      60            free (dirname);
      61            dirname = xstrdup (temp_name);
      62            free (temp_name);
      63          }
      64        else
      65          {
      66  #ifndef __MINGW32__
      67            struct passwd *user_entry;
      68  #endif
      69            char *username = xmalloc (257);
      70            int i, c;
      71  
      72            for (i = 1; (c = dirname[i]); i++)
      73              {
      74                if (IS_SLASH (c))
      75                  break;
      76                else
      77                  username[i - 1] = c;
      78              }
      79            username[i - 1] = 0;
      80  
      81  #ifndef __MINGW32__
      82            user_entry = (struct passwd *) getpwnam (username);
      83            if (user_entry)
      84              {
      85                temp_name = xmalloc (1 + strlen (user_entry->pw_dir)
      86                                     + strlen (&dirname[i])); 
      87                strcpy (temp_name, user_entry->pw_dir);
      88                strcat (temp_name, &dirname[i]);
      89  
      90                free (dirname);
      91                dirname = xstrdup (temp_name);
      92                free (temp_name);
      93              }
      94  
      95            endpwent ();
      96            free (username);
      97  #else
      98  	  free (dirname);
      99  	  dirname = xstrdup (temp_name);
     100  	  free (temp_name);
     101  #endif
     102          }
     103      }
     104    return dirname;
     105  }