1/*
2   Unix SMB/Netbios implementation.
3   Version 1.9.
4   Copyright (C) Andrew Tridgell 1992-1998
5
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 2 of the License, or
9   (at your option) any later version.
10
11   This program 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 this program; if not, write to the Free Software
18   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21/*
22   netatalk.c : routines for improving interaction between Samba and netatalk.
23   Copyright (C) John D. Blair <jdblair@cobaltnet.com> 1998
24                 Cobalt Networks, Inc.
25*/
26
27#include "includes.h"
28
29#ifdef WITH_NETATALK
30
31extern int DEBUGLEVEL;
32
33/*****************
34   ntalk_resourcepath: creates the path to the netatalk resource fork for
35                        a given file
36
37   fname:       normal filename
38   doublename:  buffer that will contain the location of the resource fork
39   length:      length of this buffer (to prevent overflows)
40
41   NOTE: doesn't currently gracefully deal with buffer overflows- it just
42         doesn't allow them to occur.
43******************/
44void ntalk_resourcepath(const char *fname, char *doublename, const int length)
45{
46  int i;
47  int charnum;
48  int lastslash;
49  char appledouble[] = APPLEDOUBLE;
50
51  /* copy fname to doublename and find last slash */
52  for (i = 0; (fname[i] != 0) && (i <= length); i++) {
53    if (fname[i] == '/') {
54      lastslash = i;
55    }
56    doublename[i] = fname[i];
57  }
58  lastslash++; /* location just after last slash */
59
60  /* insert .AppleDouble */
61  charnum = lastslash;
62  for (i = 0; (appledouble[i] != 0) && (i <= length); i++) {
63    doublename[charnum] = appledouble[i];
64    charnum++;
65  }
66
67  /* append last part of file name */
68  for (i = lastslash; (fname[i] != 0) && (i <= length); i++) {
69    doublename[charnum] = fname[i];
70    charnum++;
71  }
72
73  doublename[charnum] = 0;
74}
75
76/**********************
77 ntalk_mkresdir: creates a new .AppleDouble directory (if necessary)
78                 for the resource fork of a specified file
79**********************/
80int ntalk_mkresdir(const char *fname)
81{
82  char fdir[255];
83  int i;
84  int lastslash;
85  SMB_STRUCT_STAT dirstats;
86  char appledouble[] = APPLEDOUBLE;
87
88  /* find directory containing fname */
89  for (i = 0; (fname[i] != 0) && (i <= 254); i++) {
90    fdir[i] = fname[i];
91    if (fdir[i] == '/') {
92      lastslash = i;
93    }
94  }
95  lastslash++;
96  fdir[lastslash] = 0;
97  sys_lstat(fdir, &dirstats);
98
99  /* append .AppleDouble */
100  for (i = 0; (appledouble[i] != 0) && (lastslash <= 254); i++) {
101    fdir[lastslash] = appledouble[i];
102    lastslash++;
103  }
104  fdir[lastslash] = 0;
105
106  /* create this directory */
107  /* silently ignore EEXIST error */
108  if ((mkdir(fdir, dirstats.st_mode) < 0) && (errno != EEXIST)) {
109    return errno;
110  }
111
112  /* set ownership of this dir to the same as its parent */
113  /* holy race condition, batman! */
114  /* warning: this doesn't check for errors */
115  chown(fdir, dirstats.st_uid, dirstats.st_gid);
116
117  printf("%s\n", fdir);
118
119  return 1;
120}
121
122/**********************
123 ntalk_unlink: unlink a file and its resource fork
124**********************/
125int ntalk_unlink(const char *fname)
126{
127  char buf[255];
128
129  ntalk_resourcepath(fname, buf, 255);
130  unlink(buf);
131  return unlink(fname);
132}
133
134/**********************
135 ntalk_chown: chown a file and its resource fork
136**********************/
137int ntalk_chown(const char *fname, const uid_t uid, const gid_t gid)
138{
139  char buf[255];
140
141  ntalk_resourcepath(fname, buf, 255);
142  chown(buf, uid, gid);
143  return chown(fname, uid, gid);
144}
145
146/**********************
147 ntalk_chmod: chmod a file and its resource fork
148**********************/
149int ntalk_chmod(const char *fname, mode_t perms)
150{
151  char buf[255];
152
153  ntalk_resourcepath(fname, buf, 255);
154  chmod(buf, perms);
155  return chmod(fname, perms);
156}
157
158
159#endif /* WITH_NETATALK */
160