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