aboutsummaryrefslogtreecommitdiff
path: root/gnu/libexec/uucp/libunix/locfil.c
blob: 4e0a5f9b8eb873ff3a89793f0d06a537b83ed261 (plain) (blame)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* locfil.c
   Expand a file name on the local system.

   Copyright (C) 1991, 1992, 1993 Ian Lance Taylor

   This file is part of the Taylor UUCP package.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   The author of the program may be contacted at ian@airs.com or
   c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139.
   */

#include "uucp.h"

#include "uudefs.h"
#include "sysdep.h"
#include "system.h"

#include <pwd.h>

#if GETPWNAM_DECLARATION_OK
#ifndef getpwnam
extern struct passwd *getpwnam ();
#endif
#endif

/* Turn a file name into an absolute path, by doing tilde expansion
   and moving any other type of file into the public directory.  */

char *
zsysdep_local_file (zfile, zpubdir, pfbadname)
     const char *zfile;
     const char *zpubdir;
     boolean *pfbadname;
{
  const char *zdir;

  if (pfbadname != NULL)
    *pfbadname = FALSE;

  if (*zfile == '/')
    return zbufcpy (zfile);

  if (*zfile != '~')
    zdir = zpubdir;
  else
    {
      if (zfile[1] == '\0')
	return zbufcpy (zpubdir);

      if (zfile[1] == '/')
	{
	  zdir = zpubdir;
	  zfile += 2;
	}
      else
	{
	  size_t cuserlen;
	  char *zcopy;
	  struct passwd *q;

	  ++zfile;
	  cuserlen = strcspn ((char *) zfile, "/");
	  zcopy = zbufalc (cuserlen + 1);
	  memcpy (zcopy, zfile, cuserlen);
	  zcopy[cuserlen] = '\0';

	  q = getpwnam (zcopy);
	  if (q == NULL)
	    {
	      ulog (LOG_ERROR, "User %s not found", zcopy);
	      ubuffree (zcopy);
	      if (pfbadname != NULL)
		*pfbadname = TRUE;
	      return NULL;
	    }
	  ubuffree (zcopy);

	  if (zfile[cuserlen] == '\0')
	    return zbufcpy (q->pw_dir);

	  zdir = q->pw_dir;
	  zfile += cuserlen + 1;
	}
    }

  return zsysdep_in_dir (zdir, zfile);
}