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