Adding George's Mac extension code.
[samba.git] / source / lib / streams.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "MacExtensions.h"
24
25 extern int DEBUGLEVEL;
26
27 /*
28 ** Given a path to file/directory build a path to the stream in question.
29 ** If it is not a directory they place the .streams folder after the last
30 ** slash then add the filename with the stream cat on. If it is a directory
31 ** then just cat the .streams folder and the stream on it. If mode is true
32 ** then force the .streams directory to be created.
33 **
34 ** Some examples.
35 **   input::
36 **              fname = folder1/folder2/filea
37 **              stream = :AFP_Resource:$DATA the resource fork
38 **              isDir = False
39 **   output::           
40 **              streampath = folder1/folder2/.streams/filea:AFP_Resource:$DATA
41 **
42 **   input::
43 **              fname = folder1/folder2
44 **              stream = :AFP_AfpInfo:$DATA the Finder Info
45 **              isDir = True
46 **   output::           
47 **              streampath = folder1/folder2/.streams/:AFP_Resource:$DATA               
48 ** 
49 */ 
50 void makestreampath(char *fname, char *stream, char *streampath, int mode, int isDir, int dirOnly)
51 {
52         char *cptr;
53
54         pstrcpy(streampath, fname);
55         if (!isDir)
56         {
57                 cptr = strrchr(streampath, '/');
58                 if (cptr) *(cptr+1) = 0;
59                 else streampath[0] = 0;
60         }
61         else
62         if (streampath[0] == 0)         /* Start at the current position */
63                 pstrcat(streampath, "./");
64         else  pstrcat(streampath, "/");
65
66         pstrcat(streampath, STREAM_FOLDER_SLASH);
67         if (mode)
68                 (void)mkdir(streampath, 0777);
69         if (! dirOnly)
70         {
71                 cptr = strrchr(fname, '/');
72                 if (!isDir)
73                 {
74                         cptr = strrchr(fname, '/');
75                         if (cptr) pstrcat(streampath, cptr+1);
76                         else pstrcat(streampath, fname);
77                 }
78                 pstrcat(streampath, stream);
79         }
80         DEBUG(4,("MACEXTENSION-makestreampath: streampath = %s\n", streampath));
81 }
82
83 /*
84 ** Given a path to file/directory open the stream in question.
85 */ 
86 int openstream(char *fname, char *stream, int oflag, int mode, int isDir)
87 {
88         pstring streampath;
89         char *cptr;
90
91         makestreampath(fname, stream, streampath, mode, isDir, False);
92         return(open(streampath, oflag, mode));
93 }
94
95 /*
96 ** Fill in the AFP structure with the default values and
97 ** then write it out.
98 */ 
99 void writedefaultafp(int fd, SambaAfpInfo *safp, int writeit)
100 {
101         safp->afp.afpi_Signature = AFP_Signature;               /* Must be *(PDWORD)"AFP" */
102         safp->afp.afpi_Version = AFP_Version;                           /* Must be 0x00010000 */
103         safp->afp.afpi_Reserved1 = 0;
104         safp->afp.afpi_BackupTime = AFP_BackupTime;             /* Backup time for the file/dir */
105         bzero(safp->afp.afpi_FinderInfo, AFP_FinderSize);       /* Finder Info (32 bytes) */
106         bzero(safp->afp.afpi_ProDosInfo, 6);    /* ProDos Info (6 bytes) # */
107         bzero(safp->afp.afpi_Reserved2, 6);
108         safp->createtime = time(NULL);
109         if (writeit) (void)write(fd, safp, sizeof(*safp));
110 }
111
112 /*
113 ** Check to see if the fname has a stream component. 
114 ** If it does then check to see if it is the data fork
115 ** stream. If so then just remove the stream since we
116 ** treat them the same otherwise build a path to the 
117 ** streams folder.
118 ** Return true if it is a stream
119 ** Return false no stream and the name has not been touched.
120 */ 
121 int CheckForStream(char *fname)
122 {
123         pstring streampath;
124         char *cptr;
125
126         cptr = strrchr(fname, ':');
127         /* Must be a streams file */
128         if (cptr && strequal(cptr, DefaultStreamTest))
129     {
130         cptr = strstr(fname, AFPDATA_STREAM);
131         if (cptr) *cptr = 0;/* The datafork just remove the stream name */
132         else                            /* Build the streams path */
133         {
134                         makestreampath(fname, "", streampath, 1, False, False);
135                         pstrcpy(fname, streampath);
136         }
137         return(True);
138     }
139     return(False);
140 }