tilde.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* tilde.c -- tilde expansion code (~/foo := $HOME/foo).
  2. $Id$
  3. Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1996, 1998, 1999,
  4. 2002, 2004, 2006, 2007, 2008, 2012, 2013, 2017 Free Software
  5. Foundation, Inc.
  6. This program 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 3 of the License, or
  9. (at your option) any later version.
  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. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. Originally written by Brian Fox. */
  17. #include "info.h"
  18. #include "tilde.h"
  19. /* Do the work of tilde expansion on FILENAME. FILENAME starts with a
  20. tilde. */
  21. char *
  22. tilde_expand_word (const char *filename)
  23. {
  24. char *dirname = filename ? xstrdup (filename) : NULL;
  25. if (dirname && *dirname == '~')
  26. {
  27. char *temp_name;
  28. if (!dirname[1] || IS_SLASH (dirname[1]))
  29. {
  30. /* Prepend $HOME to the rest of the string. */
  31. char *temp_home = getenv ("HOME");
  32. /* If there is no HOME variable, look up the directory in
  33. the password database. */
  34. if (!temp_home)
  35. {
  36. #ifndef __MINGW32__
  37. struct passwd *entry;
  38. entry = (struct passwd *) getpwuid (getuid ());
  39. if (entry)
  40. temp_home = entry->pw_dir;
  41. #else
  42. temp_home = ".";
  43. #endif
  44. }
  45. temp_name = xmalloc (1 + strlen (&dirname[1])
  46. + (temp_home ? strlen (temp_home) : 0));
  47. if (temp_home)
  48. strcpy (temp_name, temp_home);
  49. else
  50. temp_name[0] = 0;
  51. strcat (temp_name, &dirname[1]);
  52. free (dirname);
  53. dirname = xstrdup (temp_name);
  54. free (temp_name);
  55. }
  56. else
  57. {
  58. #ifndef __MINGW32__
  59. struct passwd *user_entry;
  60. #endif
  61. char *username = xmalloc (257);
  62. int i, c;
  63. for (i = 1; (c = dirname[i]); i++)
  64. {
  65. if (IS_SLASH (c))
  66. break;
  67. else
  68. username[i - 1] = c;
  69. }
  70. username[i - 1] = 0;
  71. #ifndef __MINGW32__
  72. user_entry = (struct passwd *) getpwnam (username);
  73. if (user_entry)
  74. {
  75. temp_name = xmalloc (1 + strlen (user_entry->pw_dir)
  76. + strlen (&dirname[i]));
  77. strcpy (temp_name, user_entry->pw_dir);
  78. strcat (temp_name, &dirname[i]);
  79. free (dirname);
  80. dirname = xstrdup (temp_name);
  81. free (temp_name);
  82. }
  83. endpwent ();
  84. free (username);
  85. #else
  86. free (dirname);
  87. dirname = xstrdup (temp_name);
  88. free (temp_name);
  89. #endif
  90. }
  91. }
  92. return dirname;
  93. }