1 /* 2 * Copyright 2005-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include "fs_shell_command_unix.h" 7 8 #include <errno.h> 9 #include <stdio.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <sys/socket.h> 13 #include <sys/un.h> 14 15 #include "fs_shell_command.h" 16 17 18 static bool 19 write_data(int fd, const void* _buffer, size_t toWrite) 20 { 21 const char* buffer = (const char*)_buffer; 22 23 ssize_t bytesWritten; 24 do { 25 bytesWritten = write(fd, buffer, toWrite); 26 if (bytesWritten > 0) { 27 buffer += bytesWritten; 28 toWrite -= bytesWritten; 29 } 30 } while (toWrite > 0 && !(bytesWritten < 0 && errno != EINTR)); 31 32 return (bytesWritten >= 0); 33 } 34 35 36 bool 37 send_external_command(const char *command, int *result) 38 { 39 external_command_message message; 40 message.command_length = strlen(command); 41 42 // create a socket 43 int fd = socket(AF_UNIX, SOCK_STREAM, 0); 44 if (fd < 0) { 45 fprintf(stderr, "Error: Failed to open unix socket: %s\n", 46 strerror(errno)); 47 return false; 48 } 49 50 // connect to the fs_shell 51 sockaddr_un addr; 52 addr.sun_family = AF_UNIX; 53 strcpy(addr.sun_path, kFSShellCommandSocketAddress); 54 int addrLen = addr.sun_path + strlen(addr.sun_path) + 1 - (char*)&addr; 55 if (connect(fd, (sockaddr*)&addr, addrLen) < 0) { 56 fprintf(stderr, "Error: Failed to open connection to FS shell: %s\n", 57 strerror(errno)); 58 close(fd); 59 return false; 60 } 61 62 // send the command message and the command 63 if (!write_data(fd, &message, sizeof(message)) 64 || !write_data(fd, command, message.command_length)) { 65 fprintf(stderr, "Error: Writing to fs_shell failed: %s\n", 66 strerror(errno)); 67 close(fd); 68 return false; 69 } 70 71 // read the reply 72 external_command_reply reply; 73 int toRead = sizeof(reply); 74 char *replyBuffer = (char*)&reply; 75 while (toRead > 0) { 76 int bytesRead = read(fd, replyBuffer, toRead); 77 if (bytesRead < 0) { 78 if (errno == EINTR) { 79 continue; 80 } else { 81 fprintf(stderr, "Error: Failed to read reply from fs_shell: " 82 "%s\n", strerror(errno)); 83 close(fd); 84 return false; 85 } 86 } 87 88 if (bytesRead == 0) { 89 fprintf(stderr, "Error: Unexpected end of fs_shell reply. Was " 90 "still expecting %d bytes\n", toRead); 91 close(fd); 92 return false; 93 } 94 95 replyBuffer += bytesRead; 96 toRead -= bytesRead; 97 } 98 close(fd); 99 100 *result = reply.error; 101 return true; 102 } 103 104