1 /* utftpd_novc: the "no version control" version control */
2 
3 /*
4  * Copyright (C) 1999 Uwe Ohse
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 #include "config.h"
22 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <netinet/in.h>
27 
28 #include "no_tftp.h"
29 
30 #include <syslog.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include "utftpd.h"
35 
36 /* every file is under "no version control" */
37 static int
38 novc_test(const char *filename, struct utftpd_ctrl *flags)
39 {
40 	(void) filename;
41 	(void) flags;
42 	return 0;
43 }
44 
45 static int
46 novc_commit (const char *comment, struct utftpd_ctrl *flags)
47 {
48 	(void) comment;
49 #ifdef HAVE_FSYNC
50 	if (fsync(flags->filefd)==-1)  {
51 		syslog(LOG_ERR,"unable to fsync: %s", strerror(errno));
52 		do_nak(flags->remotefd,EUNDEF,"unable to fsync");
53 		_exit(1);
54 	}
55 #else
56 # ifndef (O_SYNC)
57     sync();
58 # endif
59 #endif
60 	if (close (flags->filefd) == -1) {
61 		syslog(LOG_ERR,"unable to close: %s", strerror(errno));
62 		do_nak(flags->remotefd,EUNDEF,"unable to close");
63 		_exit(1);
64 	}
65 	return 0;
66 }
67 
68 static int
69 novc_checkout(int mode, struct utftpd_ctrl *flags)
70 {
71 	int fd;
72 #define ADD_ON 0
73 #ifndef HAVE_FSYNC
74 # ifdef (O_SYNC)
75 #  undef ADD_ON
76 #  define ADD_ON O_SYNC
77 # endif
78 #endif
79 
80 	if (mode==TSG_READ) {
81 		fd=open(flags->filename,O_RDONLY);
82 	} else if (mode==TSG_CREATE) {
83 		fd=open(flags->filename,O_WRONLY|O_CREAT|O_EXCL|ADD_ON,0644);
84 	} else {
85 		fd=open(flags->filename,O_WRONLY|O_TRUNC|ADD_ON,0644);
86 	}
87 	if (fd==-1) {
88 		const char *er=strerror(errno);
89 		syslog(LOG_ERR,"open %s: %s",flags->filename,er);
90 		/* magic stuff. Basically this is catastropheprevention in case of a TFTP read
91 		 * request to a broadcast address.
92 		 */
93 		if (mode==TSG_READ && opt_suppress_naks && *flags->origfilename!='/') {
94 			if (opt_verbose) syslog(LOG_INFO,"suppressing NAK for nonexistant file");
95 			_exit(0);
96 		}
97 		do_nak(flags->remotefd,EUNDEF,er);
98 		_exit(1);
99 	}
100 	flags->filefd=fd;
101 	return 0;
102 }
103 
104 
105 struct utftpd_vc utftpd_novc={
106 	novc_test,
107 	novc_commit,
108 	novc_checkout,
109 	NULL
110 };
111