static void do_write (void) { int handle, count, status, written = 0; char buf[8192]; rpc_get (msock, RPC_INT, &handle, RPC_INT, &count, RPC_END); status = 0; while (count) { int nbytes = count > 8192 ? 8192 : count; rpc_get (msock, RPC_BLOCK, nbytes, buf, RPC_END); status = write (handle, buf, nbytes); if (status < 0) { send_status (status, errno); return; } /* FIXED: amount written must be returned to caller */ written += status; if (status < nbytes) { send_status (written, errno); return; } count -= nbytes; } send_status (written, errno); }
/* FIXME: Implement the anonymous login */ static void do_login (void) { char *username; char *password; int result; rpc_get (msock, RPC_LIMITED_STRING, &up_dir, RPC_LIMITED_STRING, &username, RPC_END); if (verbose) printf ("username: %s\n", username); if (r_auth) { logged_in = do_rauth (msock); if (logged_in) { login_reply (logged_in); return; } } rpc_send (msock, RPC_INT, MC_NEED_PASSWORD, RPC_END); rpc_get (msock, RPC_INT, &result, RPC_END); if (result == MC_QUIT) DO_QUIT_VOID (); if (result != MC_PASS) { if (verbose) printf ("do_login: Unknown response: %d\n", result); DO_QUIT_VOID (); } rpc_get (msock, RPC_LIMITED_STRING, &password, RPC_END); logged_in = do_auth (username, password); endpwent (); login_reply (logged_in); }
static void do_read (void) { int handle, count, n; void *data; rpc_get (msock, RPC_INT, &handle, RPC_INT, &count, RPC_END); data = malloc (count); if (!data) { send_status (-1, ENOMEM); return; } if (verbose) printf ("count=%d\n", count); n = read (handle, data, count); if (verbose) printf ("result=%d\n", n); if (n < 0) { send_status (-1, errno); return; } send_status (n, 0); rpc_send (msock, RPC_BLOCK, n, data, RPC_END); g_free (data); }
static void do_utime (void) { char *file; int status; long atime; long mtime; char *as; char *ms; struct utimbuf times; rpc_get (msock, RPC_STRING, &file, RPC_STRING, &as, RPC_STRING, &ms, RPC_END); sscanf (as, "%lx", &atime); sscanf (ms, "%lx", &mtime); if (verbose) printf ("Got a = %s, m = %s, comp a = %ld, m = %ld\n", as, ms, atime, mtime); g_free (as); g_free (ms); times.actime = (time_t) atime; times.modtime = (time_t) mtime; status = utime (file, ×); send_status (status, errno); g_free (file); }
static void do_closedir (void) { int handle; rpc_get (msock, RPC_INT, &handle, RPC_END); close_handle (handle - 1); }
static void do_close (void) { int handle, status; rpc_get (msock, RPC_INT, &handle, RPC_END); status = close (handle); send_status (status, errno); }
static void do_lseek (void) { int handle, offset, whence, status; rpc_get (msock, RPC_INT, &handle, RPC_INT, &offset, RPC_INT, &whence, RPC_END); status = lseek (handle, offset, whence); send_status (status, errno); }
static void do_chmod (void) { char *file; int mode, status; rpc_get (msock, RPC_STRING, &file, RPC_INT, &mode, RPC_END); status = chmod (file, mode); send_status (status, errno); g_free (file); }
static void do_unlink (void) { char *file; int status; rpc_get (msock, RPC_STRING, &file, RPC_END); status = unlink (file); send_status (status, errno); g_free (file); }
static void do_link (void) { char *f1, *f2; int status; rpc_get (msock, RPC_STRING, &f1, RPC_STRING, &f2, RPC_END); status = link (f1, f2); send_status (status, errno); g_free (f1); g_free (f2); }
static void do_chown (void) { char *file; int owner, group, status; rpc_get (msock, RPC_STRING, &file, RPC_INT, &owner, RPC_INT, &group, RPC_END); status = chown (file, owner, group); send_status (status, errno); g_free (file); }
static void check_version (void) { int version; rpc_get (msock, RPC_INT, &version, RPC_END); if (version >= 1 && version <= RPC_PROGVER) rpc_send (msock, RPC_INT, MC_VERSION_OK, RPC_END); else rpc_send (msock, RPC_INT, MC_VERSION_MISMATCH, RPC_END); clnt_version = version; }
static void do_open (void) { int handle, flags, mode; char *arg; rpc_get (msock, RPC_STRING, &arg, RPC_INT, &flags, RPC_INT, &mode, RPC_END); handle = open (arg, flags, mode); send_status (handle, errno); g_free (arg); }
int flux_rpc_get_raw (flux_rpc_t *rpc, void *data, int *len) { int rc = -1; assert (rpc->magic == RPC_MAGIC); if (rpc_get (rpc) < 0) goto done; if (flux_response_decode_raw (rpc->rx_msg, NULL, data, len) < 0) goto done; rc = 0; done: return rc; }
int flux_rpc_get (flux_rpc_t *rpc, const char **json_str) { int rc = -1; assert (rpc->magic == RPC_MAGIC); if (rpc_get (rpc) < 0) goto done; if (flux_response_decode (rpc->rx_msg, NULL, json_str) < 0) goto done; rc = 0; done: return rc; }
static void do_lstat (void) { struct stat st; char *file; int n; rpc_get (msock, RPC_STRING, &file, RPC_END); n = lstat (file, &st); send_status (n, errno); if (n >= 0) send_stat_info (&st); g_free (file); }
static void server (int sock) { int command; msock = sock; quit_server = 0; check_version (); do { if (rpc_get (sock, RPC_INT, &command, RPC_END) && (logged_in || command == MC_LOGIN)) exec_command (command); } while (!quit_server); }
static void do_fstat (void) { int handle; int n; struct stat st; rpc_get (msock, RPC_INT, &handle, RPC_END); n = fstat (handle, &st); send_status (n, errno); if (n < 0) return; send_stat_info (&st); }
static void do_opendir (void) { int handle, i; char *arg; DIR *p; rpc_get (msock, RPC_STRING, &arg, RPC_END); if (mcfs_DIR.used == OPENDIR_HANDLES) { send_status (-1, ENFILE); /* Error */ g_free (arg); return; } handle = -1; for (i = 0; i < OPENDIR_HANDLES; i++) { if (mcfs_DIR.dirs[i] == 0) { handle = i; break; } } if (handle == -1) { send_status (-1, EMFILE); g_free (arg); if (!inetd_started) fprintf (stderr, "OOPS! you have found a bug in mc - do_opendir()!\n"); return; } if (verbose) printf ("handle=%d\n", handle); p = opendir (arg); if (p) { mcfs_DIR.dirs[handle] = p; mcfs_DIR.names[handle] = arg; mcfs_DIR.used++; /* Because 0 is an error value */ rpc_send (msock, RPC_INT, handle + 1, RPC_INT, 0, RPC_END); } else { send_status (-1, errno); g_free (arg); } }
static int flux_rpc_vgetf (flux_rpc_t *rpc, const char *fmt, va_list ap) { int rc = -1; const char *json_str; assert (rpc->magic == RPC_MAGIC); if (rpc_get (rpc) < 0) goto done; if (flux_response_decode (rpc->rx_msg, NULL, &json_str) < 0) goto done; if (flux_msg_vget_jsonf (rpc->rx_msg, fmt, ap) < 0) goto done; rc = 0; done: return rc; }
static void do_readlink (void) { char buffer[2048]; char *file; int n; rpc_get (msock, RPC_STRING, &file, RPC_END); n = readlink (file, buffer, 2048 - 1); send_status (n, errno); if (n >= 0) { buffer[n] = 0; rpc_send (msock, RPC_STRING, buffer, RPC_END); } g_free (file); }
int flux_rpc_get_nodeid (flux_rpc_t *rpc, uint32_t *nodeid) { int rc = -1; uint32_t tag; assert (rpc->magic == RPC_MAGIC); if (rpc_get (rpc) < 0) goto done; if (flux_msg_get_matchtag (rpc->rx_msg, &tag) < 0) goto done; if ((tag & FLUX_MATCHTAG_GROUP_MASK) > 0) *nodeid = tag & ~FLUX_MATCHTAG_GROUP_MASK; else *nodeid = rpc->nodeid; rc = 0; done: return rc; }
/* Sends the complete directory listing, as well as the stat information */ static void do_readdir (void) { struct dirent *dirent; struct stat st; int handle, n; rpc_get (msock, RPC_INT, &handle, RPC_END); if (!handle) { rpc_send (msock, RPC_INT, 0, RPC_END); return; } /* We incremented it in opendir */ handle--; while ((dirent = readdir (mcfs_DIR.dirs[handle]))) { int fname_len; char *fname; int length = NLENGTH (dirent); rpc_send (msock, RPC_INT, length, RPC_END); rpc_send (msock, RPC_BLOCK, length, dirent->d_name, RPC_END); fname_len = strlen (mcfs_DIR.names[handle]) + strlen (dirent->d_name) + 2; fname = malloc (fname_len); snprintf (fname, fname_len, "%s/%s", mcfs_DIR.names[handle], dirent->d_name); n = lstat (fname, &st); g_free (fname); send_status (n, errno); if (n >= 0) send_stat_info (&st); } rpc_send (msock, RPC_INT, 0, RPC_END); }