* <wouter@debian.org>
*/
-/* used in cliserv.h, so must come first */
-#define MY_NAME "nbd_server"
/* Includes LFS defines, which defines behaviours of some of the following
* headers, so must come before those */
-#include "cliserv.h"
+#include "config.h"
+#include "lfs.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h> /* wait */
+#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
+#endif
#include <sys/param.h>
+#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h> /* For BLKGETSIZE */
+#endif
#include <signal.h> /* sigaction */
#include <netinet/tcp.h>
#include <netinet/in.h> /* sockaddr_in, htons, in_addr */
#include <strings.h>
#include <dirent.h>
+#include <glib.h>
+
+/* used in cliserv.h, so must come first */
+#define MY_NAME "nbd_server"
+#include "cliserv.h"
+
/** how much space for child PIDs we have by default. Dynamically
allocated, and will be realloc()ed if out of space, so this should
probably be fair for most situations. */
/** Logging macros, now nothing goes to syslog unless you say ISSERVER */
#ifdef ISSERVER
-#define msg2(a,b) syslog(a,b)
-#define msg3(a,b,c) syslog(a,b,c)
-#define msg4(a,b,c,d) syslog(a,b,c,d)
+#define msg2(a,b) syslog(a,"%s", b)
+#define msg3(a,b,c) syslog(a,"%s %s", b,c)
+#define msg4(a,b,c,d) syslog(a,"%s %s %s", b,c,d)
#else
-#define msg2(a,b) do { fprintf(stderr,b) ; fputs("\n",stderr) ; } while(0)
-#define msg3(a,b,c) do { fprintf(stderr,b,c); fputs("\n",stderr) ; } while(0)
-#define msg4(a,b,c,d) do { fprintf(stderr,b,c,d); fputs("\n",stderr) ; } while(0)
+#define msg2(a,b) do { fprintf(stderr,"%s\n", b) ; } while(0)
+#define msg3(a,b,c) do { fprintf(stderr,"%s %s\n", b,c); } while(0)
+#define msg4(a,b,c,d) do { fprintf(stderr,"%s %s %s\n", b,c,d); } while(0)
#endif
/* Debugging macros */
#define F_READONLY 1 /**< flag to tell us a file is readonly */
#define F_MULTIFILE 2 /**< flag to tell us a file is exported using -m */
#define F_COPYONWRITE 4 /**< flag to tell us a file is exported using copyonwrite */
-char difffilename[256]; /**< filename of the copy-on-write file. Doesn't belong here! */
+char difffilename[1024]; /**< filename of the copy-on-write file. Doesn't belong here! */
unsigned int timeout = 0; /**< disconnect timeout */
int autoreadonly = 0; /**< 1 = switch to readonly if opening readwrite isn't
possible */
{
int* status=NULL;
int i;
+ char buf[80];
pid_t pid;
while((pid=wait(status)) > 0) {
if(WIFEXITED(status)) {
- msg3(LOG_INFO, "Child exited with %d", WEXITSTATUS(status));
+ memset(buf,'\0', 80);
+ snprintf(buf, 79, "%d", WEXITSTATUS(status));
+ msg3(LOG_INFO, "Child exited with ", buf);
}
for(i=0;children[i]!=pid&&i<child_arraysize;i++);
if(i>=child_arraysize) {
- msg3(LOG_INFO, "SIGCHLD received for an unknown child with PID %ld",(long) pid);
+ memset(buf, '\0', 80);
+ snprintf(buf, 79, "%ld", (long)pid);
+ msg3(LOG_INFO, "SIGCHLD received for an unknown child with PID ", buf);
} else {
children[i]=(pid_t)0;
DEBUG2("Removing %d from the list of children", pid);
struct stat stat_buf;
int error;
- DEBUG("looking for export size with lseek SEEK_END\n");
- es = lseek(export, (off_t)0, SEEK_END);
- if (es > ((off_t)0)) {
+#ifdef HAVE_SYS_MOUNT_H
+#ifdef HAVE_SYS_IOCTL_H
+#ifdef BLKGETSIZE
+ DEBUG("looking for export size with ioctl BLKGETSIZE\n");
+ if (!ioctl(export, BLKGETSIZE, &es32) && es32) {
+ es = (off_t)es32 * (off_t)512;
return es;
- } else {
- DEBUG2("lseek failed: %d", errno==EBADF?1:(errno==ESPIPE?2:(errno==EINVAL?3:4)));
- }
+ }
+#endif /* BLKGETSIZE */
+#endif /* HAVE_SYS_IOCTL_H */
+#endif /* HAVE_SYS_MOUNT_H */
DEBUG("looking for export size with fstat\n");
stat_buf.st_size = 0;
} else {
err("fstat failed: %m");
}
-
-#ifdef BLKGETSIZE
- DEBUG("looking for export size with ioctl BLKGETSIZE\n");
- if (!ioctl(export, BLKGETSIZE, &es32) && es32) {
- es = (off_t)es32 * (off_t)512;
+
+ DEBUG("looking for export size with lseek SEEK_END\n");
+ es = lseek(export, (off_t)0, SEEK_END);
+ if (es > ((off_t)0)) {
return es;
- }
-#endif
+ } else {
+ DEBUG2("lseek failed: %d", errno==EBADF?1:(errno==ESPIPE?2:(errno==EINVAL?3:4)));
+ }
+
err("Could not find size of exported block device: %m");
return OFFT_MAX;
}
**/
int splitexport(void) {
off_t i ;
-
+
for (i=0; i<exportsize; i+=hunksize) {
char exportname3[1024];
-
- sprintf(exportname3, exportname2, i/hunksize);
+
+ if(flags & F_MULTIFILE) {
+ snprintf(exportname3, 1024, "%s.%d", exportname2, (int)(i/hunksize));
+ } else {
+ strncpy(exportname3, exportname2, 1024);
+ }
+ exportname3[1023]='\0';
printf( "Opening %s\n", exportname3 );
if ((export[i/hunksize] = open(exportname3, (flags & F_READONLY) ? O_RDONLY : O_RDWR)) == -1) {
/* Read WRITE ACCESS was requested by media is only read only */
}
if (flags & F_COPYONWRITE) {
- sprintf(difffilename,"%s-%s-%d.diff",exportname2,clientname,
+ snprintf(difffilename, 1024, "%s-%s-%d.diff",exportname2,clientname,
(int)getpid()) ;
+ difffilename[1023]='\0';
msg3(LOG_INFO,"About to create map and diff file %s",difffilename) ;
difffile=open(difffilename,O_RDWR | O_CREAT | O_TRUNC,0600) ;
if (difffile<0) err("Could not create diff file (%m)") ;
*
* @param net A network socket connected to an nbd client
**/
-void serveconnection(int net) {
+void serveconnection(int net) {
+ char buf[80];
splitexport();
if (exportsize == OFFT_MAX) {
exportsize = size_autodetect(export[0]);
if (exportsize > OFFT_MAX) {
err("Size of exported file is too big\n");
}
- else
- msg3(LOG_INFO, "size of exported file/device is %Lu",
- (unsigned long long)exportsize);
+ else {
+ memset(buf, '\0', 80);
+ snprintf(buf, 79, "%Lu", (unsigned long long)exportsize);
+ msg3(LOG_INFO, "size of exported file/device is ", buf);
+ }
setmysockopt(net);
}
/**
- * Find the name of the file we have to serve. This will use sprintf()
+ * Find the name of the file we have to serve. This will use snprintf()
* to put the IP address of the client inside a filename containing
* "%s". That name is then written to exportname2
*
if (getpeername( net, (struct sockaddr *) &addrin, &addrinlen ) < 0)
err("getsockname failed: %m");
peername = inet_ntoa(addrin.sin_addr);
- sprintf(exportname2, exportname, peername);
+ snprintf(exportname2, 1024, exportname, peername);
+ exportname2[1023]='\0';
msg4(LOG_INFO, "connect from %s, assigned file is %s",
peername, exportname2);