#include <sys/mount.h> /* For BLKGETSIZE */
#endif
#include <signal.h> /* sigaction */
+#include <errno.h>
#include <netinet/tcp.h>
#include <netinet/in.h> /* sockaddr_in, htons, in_addr */
#include <netdb.h> /* hostent, gethostby*, getservby* */
}
serve=g_new0(SERVER, 1);
serve->authname = g_strdup(default_authname);
+ serve->virtstyle=VIRT_IPLIT;
while((c=getopt_long(argc, argv, "-a:C:cl:mo:rp:", long_options, &i))>=0) {
switch (c) {
case 1:
/** sending macro. */
#define SEND(net,reply) writeit( net, &reply, sizeof( reply ));
/** error macro. */
-#define ERROR(client,reply) { reply.error = htonl(-1); SEND(client->net,reply); reply.error = 0; }
+#define ERROR(client,reply,errcode) { reply.error = htonl(errcode); SEND(client->net,reply); reply.error = 0; }
/**
* Serve a file to a single client.
*
memcpy(reply.handle, request.handle, sizeof(reply.handle));
if ((request.from + len) > (OFFT_MAX)) {
DEBUG("[Number too large!]");
- ERROR(client, reply);
+ ERROR(client, reply, EINVAL);
continue;
}
if (((ssize_t)((off_t)request.from + len) > client->exportsize)) {
DEBUG("[RANGE!]");
- ERROR(client, reply);
+ ERROR(client, reply, EINVAL);
continue;
}
if ((client->server->flags & F_READONLY) ||
(client->server->flags & F_AUTOREADONLY)) {
DEBUG("[WRITE to READONLY!]");
- ERROR(client, reply);
+ ERROR(client, reply, EPERM);
continue;
}
if (expwrite(request.from, buf, len, client)) {
DEBUG("Write failed: %m" );
- ERROR(client, reply);
+ ERROR(client, reply, errno);
continue;
}
SEND(client->net, reply);
DEBUG("exp->buf, ");
if (expread(request.from, buf + sizeof(struct nbd_reply), len, client)) {
DEBUG("Read failed: %m");
- ERROR(client, reply);
+ ERROR(client, reply, errno);
continue;
}
gchar* cmd;
int retval=0;
- if(*command) {
+ if(command && *command) {
cmd = g_strdup_printf(command, file);
retval=system(cmd);
g_free(cmd);
* @param client a connected client
**/
void serveconnection(CLIENT *client) {
+ if(do_run(client->server->prerun, client->exportname)) {
+ exit(EXIT_FAILURE);
+ }
setupexport(client);
if (client->server->flags & F_COPYONWRITE) {
setmysockopt(client->net);
- if(!do_run(client->server->prerun, client->exportname)) {
- mainloop(client);
- }
+ mainloop(client);
do_run(client->server->postrun, client->exportname);
}
}
/* child */
g_hash_table_destroy(children);
- for(i=0;i<servers->len,serve=(g_array_index(servers, SERVER*, i));i++) {
+ for(i=0;i<servers->len;i++) {
+ serve=g_array_index(servers, SERVER*, i);
close(serve->socket);
}
/* FALSE does not free the
void dousers(void) {
struct passwd *pw;
struct group *gr;
- if(runuser) {
- pw=getpwnam(runuser);
- if(setuid(pw->pw_uid)<0)
- msg3(LOG_DEBUG, "Could not set UID: %s", strerror(errno));
- }
if(rungroup) {
gr=getgrnam(rungroup);
if(setgid(gr->gr_gid)<0)
msg3(LOG_DEBUG, "Could not set GID: %s", strerror(errno));
}
+ if(runuser) {
+ pw=getpwnam(runuser);
+ if(setuid(pw->pw_uid)<0)
+ msg3(LOG_DEBUG, "Could not set UID: %s", strerror(errno));
+ }
}
/**
serve=cmdline(argc, argv);
servers = parse_cfile(config_file_pos, &err);
if(!servers || !servers->len) {
- g_warning("Could not parse config file: %s", err->message);
+ g_warning("Could not parse config file: %s",
+ err ? err->message : "Unknown error");
}
if(serve) {
g_array_append_val(servers, *serve);