1 /* $Id$
2 * Provides temp files & directories operating functions
3 *
4 * (c) Stas Degteff <g@grumbler.org>, 2:5080/102@fidonet
5 *
6 * Latest version may be foind on http://husky.sourceforge.net
7 *
8 *
9 * HUSKYLIB: common defines, types and functions for HUSKY
10 *
11 * This is part of The HUSKY Fidonet Software project:
12 * see http://husky.sourceforge.net for details
13 *
14 *
15 * HUSKYLIB is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU Lesser General Public
17 * License as published by the Free Software Foundation; either
18 * version 2 of the License, or (at your option) any later version.
19 *
20 * HUSKYLIB is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; see file COPYING. If not, write to the
27 * Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 * See also http://www.gnu.org, license may be found here.
30 */
31
32 /* standard headers */
33 #include <errno.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
39
40
41 /* huskylib: compiler.h */
42 #include <compiler.h>
43
44
45 /* compiler-dependent headers */
46 #ifdef HAS_UNISTD_H
47 # include <unistd.h>
48 #endif
49
50 #ifdef HAS_IO_H
51 # include <io.h>
52 #endif
53
54
55 /* huskylib headers */
56 #define DLLEXPORT
57 #include <huskyext.h>
58
59 /* huskylib headers */
60 #include <log.h>
61 #include <temp.h>
62 #include <memory.h>
63 #include <xstr.h>
64 #include <strext.h>
65
66 /*** Declarations & defines ***********************************************/
67
68
69 /*** Implementation *******************************************************/
70
71 /* If mkstemps() not implemented, use this function.
72 * parameters example:
73 * tempfilename = "/path/prefixXXXXX.suffix"
74 * tempfilename = "/path/prefixXXXXX"
75 * "XXXXX" replaced with random char sequence
76 */
MKSTEMPS(char * tempfilename)77 int MKSTEMPS( char *tempfilename )
78 { char *ttt;
79 int fd=-1;
80 char *pp;
81
82 if (tempfilename == NULL)
83 return -1;
84
85 ttt = sstrdup(tempfilename);
86 pp = strrchr(ttt, '.');
87 if( ttt[strlen(ttt)-1]!='X' && pp && (pp>ttt && *(pp-1)=='X') ){ /* suffix presents */
88 do{
89 *pp = 0;
90 if( !mktemp(ttt) )
91 break;
92 *pp = '.';
93 fd = open( ttt, O_EXCL | O_CREAT | O_RDWR, S_IREAD | S_IWRITE );
94 }while( fd==-1 && errno == EEXIST && (strcpy(ttt,tempfilename), 1) );
95 }else{
96 do{
97 if( !mktemp(ttt) )
98 break;
99 fd = open( ttt, O_EXCL | O_CREAT | O_RDWR, S_IREAD | S_IWRITE );
100 }while( fd==-1 && errno == EEXIST && (strcpy(ttt,tempfilename), 1) );
101 }
102 if(fd!=-1) strcpy(tempfilename,ttt);
103 nfree(ttt);
104 return fd;
105 }
106
107 /* Create new file with random name & specified suffix in specified directory.
108 * path = temporary directory
109 * ext = file name suffix
110 * mode = 'w' or 'b' - file open mode (text or binary); default = fopen() default
111 * Place to 'name' variable name of created file (from malloc() memory pool),
112 * if name is not NULL its free().
113 * Return file descriptor or NULL
114 */
115
createTempFileIn(const char * path,const char * ext,char mode,char ** name)116 FILE *createTempFileIn(const char *path, const char *ext, char mode, char **name)
117 { int tempfh=-1; FILE *tempfd=NULL; char *tempfilename=NULL;
118 char *ii=0;
119
120 if( !path || !path[0] ){
121 w_log(LL_ERR, "temp::createTempFileIn(): pathname is empty!");
122 return NULL;
123 }
124 w_log( LL_FUNC, "createtempfileIn() start" );
125
126 xstrcat( &tempfilename, (char *)path );
127 ii = tempfilename + strlen(tempfilename) -1;
128 if( *ii == PATH_DELIM ) *ii=0; /* strip trailing slash */
129
130 xscatprintf( &tempfilename, "%cXXXXXX.%s", PATH_DELIM, ext);
131
132 w_log(LL_FILENAME, "Temp. file mask: %s", tempfilename);
133
134 tempfh = MKSTEMPS(tempfilename);
135 if( tempfh == -1 )
136 { w_log( LL_ERR, "Cannot create temp. file (Mask %s): %s", tempfilename, strerror(errno) );
137 w_log( LL_FUNC, "createTempFileIn() rc=NULL" );
138 return NULL;
139 }
140 if( mode == 't' )
141 tempfd = fdopen(tempfh,"wt");
142 else if( mode == 'b' )
143 tempfd = fdopen(tempfh,"wb");
144 else
145 tempfd = fdopen(tempfh,"w");
146 if( !tempfd )
147 { w_log( LL_CRIT, "Cannot reopen file '%s': %s", tempfilename, strerror(errno) );
148 return NULL;
149 }
150 w_log( LL_FILE, "Created temp file %s", tempfilename );
151 if( name!= NULL )
152 { nfree(*name);
153 *name = sstrdup(tempfilename);
154 }
155 w_log( LL_FUNC, "createTempFileIn() OK fd=%p", tempfd );
156 return tempfd;
157 }
158
159
160 /* Create new file with random name & specified suffix (text mode).
161 * pconfig = fidoconfig structure pointer
162 * ext = file name suffix
163 * Place to 'name' variable name of created file (from malloc() memory pool),
164 * if name is not NULL its free().
165 * Return file descriptor or NULL
166 */
createTempTextFile(char * tempDir,char ** name)167 FILE *createTempTextFile(char *tempDir, char **name)
168 { if(tempDir)
169 return createTempFileIn(tempDir, TEMPFILESUFFIX, 't', name);
170 else{
171 w_log(LL_ERR, "tempDir not defined in config, temp. file can't created");
172 return NULL;
173 }
174 }
175
176 /* Create new file with random name & specified suffix (binary mode).
177 * pconfig = fidoconfig structure pointer
178 * ext = file name suffix
179 * Place to 'name' variable name of created file (from malloc() memory pool),
180 * if name is not NULL its free().
181 * Return file descriptor or NULL
182 */
createTempBinFile(char * tempDir,char ** name)183 FILE *createTempBinFile(char *tempDir, char **name)
184 { if(tempDir)
185 return createTempFileIn(tempDir, TEMPFILESUFFIX, 'b', name);
186 else{
187 w_log(LL_ERR, "tempDir not defined in config, temp. file can't created");
188 return NULL;
189 }
190 }
191
192
193 #ifdef TEST_TEMP_C
194
195 #include <string.h>
196 #include <errno.h>
197 #include <stdio.h>
198
199 /* Test */
main()200 void main()
201 { FILE *fd;
202 s_fidoconfig *config;
203 char *name=NULL;
204
205 config = readConfig("../test.cfg");
206 fd = createTempBinFile(config, &name);
207 if( !fd )
208 printf("error creating %s: %s\n", name, strerror(errno) );
209 else
210 { printf("created: %s\n", name);
211 fclose (fd);
212 unlink(name);
213 }
214 disposeConfig(config);
215 }
216 #endif
217