Beispiel #1
0
void retokenize_cmd(int cmdPosition, char *tokens[], char *bufCopy, char *buff, _Bool *in_bg) {
  strcpy(buff, history[cmdPosition]);
  strcpy(bufCopy, buff);

  int token_count = tokenize_command(buff, tokens);
  extract_background_arg(token_count, tokens, in_bg);
}
Beispiel #2
0
void read_command(char *buff, char *tokens[], _Bool *in_background)
{
    *in_background = false;

    // Read input
    int length = read(STDIN_FILENO, buff, COMMAND_LENGTH-1);
    signal(SIGINT, shell_sig_handler);
    if (length < 0 && errno == EINTR) {
        buff = NULL;
        tokens[0] = NULL;
        return;
    }
    if (length < 0) {
        perror("Unable to read command. Terminating.\n");
        exit(-1); /* terminate with error */
    }
    if ( (length < 0) && (errno != EINTR) ) {
        perror("Unable to read command. Terminating.\n");
        exit(-1); /* terminate with error */
    }   

    // Null terminate and strip \n.
    buff[length] = '\0';
    if (buff[strlen(buff) - 1] == '\n')
        buff[strlen(buff) - 1] = '\0';
    if (buff[0] == '!')
        buff = shell_retrieve_history(buff);
    if (buff == NULL) {
        tokens[0] = NULL;
        return;
    }  
    
    // Tokenize (saving original command string)
    char command[1024];
    strcpy(command, buff);
    int token_count = tokenize_command(command, tokens);
    if (token_count == 0)
        return;
    shell_add_to_history(buff);

    // Extract if running in background:
    if (token_count > 0 && strcmp(tokens[token_count - 1], "&") == 0) {
        *in_background = true;
        tokens[token_count - 1] = 0;
    }
}
static int console_loop(void)
{
	cmd_args args[16];
	char buffer[256];

	printf("entering main console loop\n");

	for (;;) {
		puts("] ");

		int len = read_line(buffer, sizeof(buffer));
		if (len == 0)
			continue;

//		printf("line = '%s'\n", buffer);

		/* tokenize the line */
		int argc = tokenize_command(buffer, args, 16);
		if (argc < 0) {
			printf("syntax error\n");
			continue;
		} else if (argc == 0) {
			continue;
		}

//		printf("after tokenize: argc %d\n", argc);
//		for (int i = 0; i < argc; i++)
//			printf("%d: '%s'\n", i, args[i].str);

		/* convert the args */
		convert_args(argc, args);

		/* try to match the command */
		const cmd *command = match_command(args[0].str);
		if (!command) {
			printf("command not found\n");
			continue;
		}

		int result = command->cmd_callback(argc, args);
                return result;
		// XXX do something with the result
	}
}
int tokenizeAndProcessCommand(char* buff, char* tokens[], _Bool* in_background) {
	// Add command in buff to history if not !n, !!, or carriage return (newline)
	if (buff[0] != '!' && buff[0] != '\0') {
		addCommandToHistory(buff);
	}

	int token_count = tokenize_command(buff, tokens);
	if (token_count == 0) {
		//error
		return 0;
	}

	// Extract & if running in background:
	if (token_count > 0 && strcmp(tokens[token_count - 1], "&") == 0) {
		*in_background = true;
		tokens[token_count - 1] = 0;
	}

	// tokenizing and processing successful
	return 1;
}
Beispiel #5
0
char* read_command(char *buff, char *tokens[], _Bool *in_background, int *token_count) {
  *in_background = false;

  // Read input
  int length = read(STDIN_FILENO, buff, COMMAND_LENGTH-1);

  if ((length < 0) && (errno !=EINTR) ){
    perror("Unable to read command. Terminating.\n");
    exit(-1);  /* terminate with error */
  }

  if ((length < 0) && (errno ==EINTR)){
    buff[0] = '\0';
    return NULL;
  }

  // Null terminate and strip \n.
  buff[length] = '\0';
  if (buff[strlen(buff) - 1] == '\n') {
    buff[strlen(buff) - 1] = '\0';
  }

  char *copy = malloc(sizeof(buff));
  strcpy(copy, buff);

  // Tokenize (saving original command string)
  *token_count = tokenize_command(buff, tokens);

  if (*token_count == 0) {
    free(copy);
    return NULL;
  }

  // Extract if running in background:
  extract_background_arg(*token_count, tokens, in_background);

  return copy;
}
Beispiel #6
0
/* 
 * Entry point for the kernel monitor. Monitor provides a simple shell with
 * a set of commands which starts when the OS boots.
 */
void monitor(void)
{
	char command_string[BUFFER_MAX_LENGTH];
	char *argv[ARG_COUNT_MAX];
	int argc = 0;

	while (true) {
		command_handler handler = NULL;
		
		kprintf("K> ");
		kgets(command_string);

		tokenize_command(command_string, &argc, argv);
		if (argc == 0)
			continue;

		handler = get_command_handler(argv[0]);
		if (handler == NULL)
			kprintf("command not found.\n");
		else
			handler(argc, argv);
	}
}
Beispiel #7
0
/* _____________________________________________________ */
int main() {
    int argc;            // Nombre d'arguments.
    char argl[MAXLIN];   // Ligne de commande "brute".
    char* argv[MAXVEC];  // Tableau d'arguments.
    // On désactive le buffer de 'stdout'.
    // (Sinon il faudrait parfois utiliser 'fflush'.)
    setvbuf(stdout, NULL, _IONBF, 0);
    status = 0;
    // Boucle infinie pouvant être interrompue par 'exit'.
    while (1) {
        // On affiche l'invite de commande.
        display_prompt();
        // On récupère la commande de l'utilisateur.
        read_command(argl);
        // On découpe cette commande en arguments.
        argc = tokenize_command(argl, argv);
        // On met à jour le tableau de jobs.
        refresh_job_table();
        // On essaye d'exécuter la commande,
        // et on stocke la valeur de retour.
        status = execute_command(argc, argv);
    }
}
Beispiel #8
0
rpc_parse_result rpc_response_parse(rpc_conn *c, rpc_response **rsp) {
	//request line
	char *el, *cont;
	int avail, num;
	rpc_response *response = NULL;
	el = memchr(c->rcurr, '\n', c->rbytes);
	avail = c->rbytes;
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		//windows newline separate is \r\n
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		token_t tokens[3];
		int n = tokenize_command(c->rcurr, tokens, 3);
		if (n != 3 && strcmp(tokens[0].value, RPC_VERSION) != 0) {
			fprintf(stderr, "status line begin error!\n");
			return RPC_Parse_Error;
		}
		response = rpc_response_new();
		response->code = (int) strtol(tokens[1].value, NULL, 10);
		response->phrase = tokens[2].value;
		c->rcurr = cont;
		c->rbytes = avail;
	} else {
		fprintf(stderr, "not status line error!\n");
		return RPC_Parse_Error;
	}
	//seq
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		num = sscanf(c->rcurr, "seq:%d", &response->seq);
		c->rcurr = cont;
		c->rbytes = avail;
		if (num != 1) {
			rpc_response_free(response);
			fprintf(stderr, "seq parse error!\n");
			return RPC_Parse_Error;
		}
	} else {
		rpc_response_free(response);
		fprintf(stderr, "not seq line error!\n");
		return RPC_Parse_Error;
	}
	//body len
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		num = sscanf(c->rcurr, "body-len:%d", &response->output_len);
		c->rcurr = cont;
		c->rbytes = avail;
		if (num != 1) {
			rpc_response_free(response);
			fprintf(stderr, "body-len line parse error!\n");
			return RPC_Parse_Error;
		}
	} else {
		rpc_response_free(response);
		fprintf(stderr, "not body-len line error!\n");
		return RPC_Parse_Error;
	}
	//new line
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr == 0) || ((el - c->rcurr) == 1 && *(el - 1) == '\r')) {
			if (avail >= response->output_len) {
				response->output = cont;
				c->rcurr = cont + response->output_len;
				c->rbytes = avail - response->output_len;
				*rsp = response;
				return RPC_Parse_OK;
			} else {
				c->rcurr = cont;
				c->rbytes = avail;
				*rsp = response;
				return RPC_Parse_NeedData;
			}
		}
	}
	fprintf(stderr, "body error!\n");
	rpc_response_free(response);
	return RPC_Parse_Error;
}
Beispiel #9
0
static status_t command_loop(int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked)
{
    bool exit;
#if WITH_LIB_ENV
    bool report_result;
#endif
    cmd_args *args = NULL;
    const char *buffer;
    const char *continuebuffer;
    char *outbuf = NULL;

    args = (cmd_args *) malloc (MAX_NUM_ARGS * sizeof(cmd_args));
    if (unlikely(args == NULL)) {
        goto no_mem_error;
    }

    const size_t outbuflen = 1024;
    outbuf = malloc(outbuflen);
    if (unlikely(outbuf == NULL)) {
        goto no_mem_error;
    }

    exit = false;
    continuebuffer = NULL;
    while (!exit) {
        // read a new line if it hadn't been split previously and passed back from tokenize_command
        if (continuebuffer == NULL) {
            if (showprompt)
                fputs("] ", stdout);

            int len = get_line(&buffer, get_line_cookie);
            if (len < 0)
                break;
            if (len == 0)
                continue;
        } else {
            buffer = continuebuffer;
        }

//      dprintf("line = '%s'\n", buffer);

        /* tokenize the line */
        int argc = tokenize_command(buffer, &continuebuffer, outbuf, outbuflen,
                                    args, MAX_NUM_ARGS);
        if (argc < 0) {
            if (showprompt)
                printf("syntax error\n");
            continue;
        } else if (argc == 0) {
            continue;
        }

//      dprintf("after tokenize: argc %d\n", argc);
//      for (int i = 0; i < argc; i++)
//          dprintf("%d: '%s'\n", i, args[i].str);

        /* convert the args */
        convert_args(argc, args);

        /* try to match the command */
        const cmd *command = match_command(args[0].str, CMD_AVAIL_NORMAL);
        if (!command) {
            if (showprompt)
                printf("command not found\n");
            continue;
        }

        if (!locked)
            mutex_acquire(command_lock);

        abort_script = false;
        lastresult = command->cmd_callback(argc, args);

#if WITH_LIB_ENV
        bool report_result;
        env_get_bool("reportresult", &report_result, false);
        if (report_result) {
            if (lastresult < 0)
                printf("FAIL %d\n", lastresult);
            else
                printf("PASS %d\n", lastresult);
        }
#endif

#if WITH_LIB_ENV
        // stuff the result in an environment var
        env_set_int("?", lastresult, true);
#endif

        // someone must have aborted the current script
        if (abort_script)
            exit = true;
        abort_script = false;

        if (!locked)
            mutex_release(command_lock);
    }

    free(outbuf);
    free(args);
    return NO_ERROR;

no_mem_error:
    if (outbuf)
        free(outbuf);

    if (args)
        free(args);

    dprintf(INFO, "%s: not enough memory\n", __func__);
    return ERR_NO_MEMORY;
}
Beispiel #10
0
// process a memcached get(s) command. (we don't support CAS).
void process_get_command(conn *c, token_t *tokens, size_t ntokens,
                                bool return_cas) {
	char *key;
	size_t nkey;
	int i = 0;
	item *it;
	token_t *key_token = &tokens[KEY_TOKEN];
	char *suffix;

	assert(c != NULL);

	if (config.alloc && c->mem_blob == NULL) {
		long size = config.alloc_mean + gsl_ran_gaussian(c->thread->r, config.alloc_stddev);
		size = size <= 0 ? 10 : size;
		if (config.verbose > 0) {
			fprintf(stderr, "allocated blob: %ld\n", size);
		}

		c->mem_blob = malloc(sizeof(char) * size);
		c->mem_free_delay = 0;

		if (config.rtt_delay) {
			double r = config.rtt_mean + gsl_ran_gaussian(c->thread->r, config.rtt_stddev);
			if (r >= config.rtt_cutoff) {
				int wait = r / 100;
				if (config.verbose > 0) {
					fprintf(stderr, "delay: %d\n", wait);
				}
				c->mem_free_delay = wait;
				conn_set_state(c, conn_mwrite);
			}
		}
	}

	// process the whole command line, (only part of it may be tokenized right now)
	do {
		// process all tokenized keys at this stage.
		while(key_token->length != 0) {
			key = key_token->value;
			nkey = key_token->length;

			if(nkey > KEY_MAX_LENGTH) {
				error_response(c, "CLIENT_ERROR bad command line format");
				return;
			}

			// lookup key-value.
			it = item_get(key, nkey);
			
			// hit.
			if (it) {
				if (i >= c->isize && !conn_expand_items(c)) {
					item_remove(it);
					break;
				}

				// Construct the response. Each hit adds three elements to the
				// outgoing data list:
				//   "VALUE <key> <flags> <data_length>\r\n"
				//   "<data>\r\n"
				// The <data> element is stored on the connection item list, not on
				// the iov list.
				if (!conn_add_iov(c, "VALUE ", 6) != 0 ||
				    !conn_add_iov(c, ITEM_key(it), it->nkey) != 0 ||
				    !conn_add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) {
					item_remove(it);
					break;
				}

				if (config.verbose > 1) {
					fprintf(stderr, ">%d sending key %s\n", c->sfd, key);
				}

				// add item to remembered list (i.e., we've taken ownership of them
				// through refcounting and later must release them once we've
				// written out the iov associated with them).
				item_update(it);
				*(c->ilist + i) = it;
				i++;
			}

			key_token++;
		}

		/*
		 * If the command string hasn't been fully processed, get the next set
		 * of tokens.
		 */
		if(key_token->value != NULL) {
			ntokens = tokenize_command(key_token->value, tokens, MAX_TOKENS);
			key_token = tokens;
		}

	} while(key_token->value != NULL);

	c->icurr = c->ilist;
	c->ileft = i;

	if (config.verbose > 1) {
		fprintf(stderr, ">%d END\n", c->sfd);
	}

	// If the loop was terminated because of out-of-memory, it is not reliable
	// to add END\r\n to the buffer, because it might not end in \r\n. So we
	// send SERVER_ERROR instead.
	if (key_token->value != NULL || !conn_add_iov(c, "END\r\n", 5) != 0) {
		error_response(c, "SERVER_ERROR out of memory writing get response");
	} else {
		conn_set_state(c, conn_mwrite);
	}
}
Beispiel #11
0
// parse a single memcached request.
bool parse_command(conn *c, char *command) {
	token_t tokens[MAX_TOKENS];
	size_t ntokens;
	int comm;

	assert(c != NULL);

	ntokens = tokenize_command(command, tokens, MAX_TOKENS);
	if (ntokens >= 3 &&
			((strcmp(tokens[COMMAND_TOKEN].value, "get") == 0) ||
			(strcmp(tokens[COMMAND_TOKEN].value, "bget") == 0))) {
		process_get_command(c, tokens, ntokens, false);

	} else if (ntokens >= 3 &&
			(strcmp(tokens[COMMAND_TOKEN].value, "gets") == 0)) {
		process_get_command(c, tokens, ntokens, true);

	} else if ((ntokens == 6 || ntokens == 7) &&
			((strcmp(tokens[COMMAND_TOKEN].value, "add") == 0 && (comm = NREAD_ADD)) ||
			(strcmp(tokens[COMMAND_TOKEN].value, "set") == 0 && (comm = NREAD_SET)) ||
			(strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)) ||
			(strcmp(tokens[COMMAND_TOKEN].value, "prepend") == 0 && (comm = NREAD_PREPEND)) ||
			(strcmp(tokens[COMMAND_TOKEN].value, "append") == 0 && (comm = NREAD_APPEND)) )) {
		process_update_command(c, tokens, ntokens, comm, false);

	} else if ((ntokens == 7 || ntokens == 8) &&
			(strcmp(tokens[COMMAND_TOKEN].value, "cas") == 0 && (comm = NREAD_CAS))) {
		process_update_command(c, tokens, ntokens, comm, true);

	/* } else if ((ntokens == 4 || ntokens == 5) && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) { */
	/* 	process_arithmetic_command(c, tokens, ntokens, 1); */

	/* } else if ((ntokens == 4 || ntokens == 5) && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) { */
	/* 	process_arithmetic_command(c, tokens, ntokens, 0); */

	/* } else if (ntokens >= 3 && ntokens <= 5 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "delete") == 0)) { */
	/* 	process_delete_command(c, tokens, ntokens); */

	/* } else if ((ntokens == 4 || ntokens == 5) && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "touch") == 0)) { */
	/* 	process_touch_command(c, tokens, ntokens); */

	} else if (ntokens >= 2 &&
			(strcmp(tokens[COMMAND_TOKEN].value, "stats") == 0)) {
		process_stat_command(c, tokens, ntokens);

	/* } else if (ntokens >= 2 && ntokens <= 4 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "flush_all") == 0)) { */
	/* 	process_flush_cmd(c, tokens, ntokens); */

	/* } else if (ntokens == 2 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "version") == 0)) { */
	/* 	process_version_cmd(c, tokens, ntokens); */

	/* } else if (ntokens == 2 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "quit") == 0)) { */
	/* 	process_quite_cmd(c, tokens, ntokens); */

	/* } else if (ntokens == 2 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "shutdown") == 0)) { */
	/* 	process_shutdown_cmd(c, tokens, ntokens); */

	/* } else if (ntokens > 1 && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "slabs") == 0)) { */
	/* 	process_slab_cmd(c, tokens, ntokens); */

	/* } else if ((ntokens == 3 || ntokens == 4) && */
	/* 		(strcmp(tokens[COMMAND_TOKEN].value, "verbosity") == 0)) { */
	/* 	process_verbosity_command(c, tokens, ntokens); */

	} else {
		return false;
	}

	// NOTE: No refcnt needed here as not changing pointer structure.
	mutex_lock(&c->stats->lock);
	c->stats->requests++;
	mutex_unlock(&c->stats->lock);

	return true;
}
Beispiel #12
0
rpc_parse_result rpc_request_parse(rpc_conn *c, rpc_request **req) {
	//request line
	char *el, *cont, *ch;
	int avail, num;
	rpc_request *request = NULL;
	el = memchr(c->rcurr, '\n', c->rbytes);
	avail = c->rbytes;
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		//windows newline separate is \r\n
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		token_t tokens[3];
		int n = tokenize_command(c->rcurr, tokens, 3);
		if (n != 3 && strcmp(tokens[0].value, "CALL") != 0) {
			fprintf(stderr, "request line begin error!\n");
			return RPC_Parse_Error;
		}
		ch = strchr(tokens[1].value, '@');
		if (!ch) {
			fprintf(stderr, "request line middler error!\n");
			return RPC_Parse_Error;
		}
		request = rpc_request_new();
		*ch = '\0';
		request->method_name = tokens[1].value;
		request->service_name = ch + 1;
		request->rpc_version = tokens[2].value;
		c->rcurr = cont;
		c->rbytes = avail;
	} else {
		fprintf(stderr, "not request line error!\n");
		return RPC_Parse_Error;
	}
	//seq
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		num = sscanf(c->rcurr, "seq:%d", &request->seq);
		c->rcurr = cont;
		c->rbytes = avail;
		if (num != 1) {
			rpc_request_free(request);
			fprintf(stderr, "seq parse error!\n");
			return RPC_Parse_Error;
		}
	} else {
		rpc_request_free(request);
		fprintf(stderr, "not seq line error!\n");
		return RPC_Parse_Error;
	}
	//body len
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr) > 1 && *(el - 1) == '\r') {
			el--;
		}
		*el = '\0';
		num = sscanf(c->rcurr, "body-len:%d", &request->input_len);
		c->rcurr = cont;
		c->rbytes = avail;
		if (num != 1) {
			rpc_request_free(request);
			fprintf(stderr, "body-len line parse error!\n");
			return RPC_Parse_Error;
		}
	} else {
		rpc_request_free(request);
		fprintf(stderr, "not body-len line error!\n");
		return RPC_Parse_Error;
	}
	//new line
	el = memchr(c->rcurr, '\n', avail);
	if (el) {
		cont = el + 1;
		avail -= (cont - c->rcurr);
		if ((el - c->rcurr == 0) || ((el - c->rcurr) == 1 && *(el - 1) == '\r')) {
			if (avail >= request->input_len) {
				request->input = cont;
				c->rcurr = cont + request->input_len;
				c->rbytes = avail - request->input_len;
				*req = request;
				return RPC_Parse_OK;
			} else {
				c->rcurr = cont;
				c->rbytes = avail;
				*req = request;
				return RPC_Parse_NeedData;
			}
		}
	}
	fprintf(stderr, "body error!\n");
	rpc_request_free(request);
	return RPC_Parse_Error;
}
Beispiel #13
0
int guts(int accept_fd, int listen_fd) {
  
  char buffer[RECV_WINDOW] = "";   // recv buffer
  int msgbuflen = MSG_SIZE;
  char status_msg[MSG_SIZE];
  char *msg; // Incoming message.
  char *send_msg; // Outgoing message.
  char *tmp_msg;
  void *msg_cursor;
  struct response_struct response;   
  int msglen = 0; // length of the assembled message that we receive.
  int recvlen = 0; // how many bytes recv call returns.
  int responselen = 0;   
  int offset;
  int retval;
  char* token_vector[MAX_ARGS] = {'\0'};
  int token_count = 0;

  // Re-register the sigterm handler to our cleanup function.
  signal(SIGTERM, sigterm_handler_child);
  close(listen_fd); // Close this resource from our parent. We don't need it any more.

  while (1) {

    msglen = 0;
    msgbuflen = MSG_SIZE;
    msg = malloc(sizeof(char) * msgbuflen);
    msg_cursor = (void*)msg;
    bzero(msg, msgbuflen);


    // Wait for some data
    while (((recvlen = recv(accept_fd, (void*)buffer, RECV_WINDOW, MSG_PEEK)) == -1) && (errno == EAGAIN));
    if (recvlen == 0) {
      fprintf(stderr, "Client closed the connection.\n");
      close(accept_fd);
      cleanup_and_exit(0);
    };

    // Receive data from our buffered stream until we would block.
    while ((recvlen = recv(accept_fd, (void*)buffer, RECV_WINDOW, 0)) != -1) {
      if (recvlen == 0) {
        fprintf(stderr, "Client closed the connection.\n");
        close(accept_fd);
        cleanup_and_exit(0);
      };

      if (recvlen == -1) {
        fprintf(stderr, "Got error %d from recv.\n", errno);
        close(accept_fd);
        cleanup_and_exit(-1);
      };

      // Extend our message buffer if need be.
      if ((msglen += recvlen) > (msgbuflen)) {
        msgbuflen += msgbuflen;
        offset = msg_cursor - (void*)msg;
        tmp_msg = malloc(sizeof(char) * msgbuflen);
        bzero(tmp_msg, msgbuflen);
        memcpy(tmp_msg, msg, offset);
        msg_cursor = tmp_msg + offset;
        free(msg);
        msg = tmp_msg;
        fprintf(stderr, "msgbuflen expanded to %d\n", msgbuflen);
      }

      memcpy(msg_cursor, (void*)buffer, recvlen);
      msg_cursor += recvlen;
      if (memchr((void*)buffer, '\n', recvlen)) break; // Got a terminator character. Go process our message.

    } 

    tmp_msg = msg;
    strsep(&tmp_msg, "\r\n");

    token_count = tokenize_command(msg, token_vector);

    switch (extract_command(token_vector, token_count))  {

      case 0: // quit
        cleanup_and_exit();
        break;

      case 1: // create
        response = create_command(token_vector, token_count);
        break;

      case 2: // read
        response = read_command(token_vector, token_count);
        break;

      case 3: // delete
        response = delete_command(token_vector, token_count);
        break;

      case 4: // subkeys
        response = keys_command(token_vector, token_count);
        break;

      default:
        if ((response.msg = malloc(sizeof(char) * MSG_SIZE)) == NULL) {
          perror(NULL);
          cleanup_and_exit; 
        }
        bzero(response.msg, MSG_SIZE);
        sprintf(response.msg, "Unknown command.");
        response.status = 1;      
    }

    responselen = prepare_send_msg(response, &send_msg);

    if((send(accept_fd, (void*)send_msg, responselen, 0) == -1)) perror("Send failed");
    free(msg);
    free(response.msg);
    free(send_msg);

  };

  return(0);
}
Beispiel #14
0
static void command_loop(int (*get_line)(const char **, void *), void *get_line_cookie, bool showprompt, bool locked)
{
	bool exit;
	bool report_result;
	cmd_args args[16];
	const char *buffer;
	const char *continuebuffer;
	char *outbuf;

	const size_t outbuflen = 1024;
	outbuf = malloc(outbuflen);

	exit = false;
	continuebuffer = NULL;
	while (!exit) {
		// read a new line if it hadn't been split previously and passed back from tokenize_command
		if (continuebuffer == NULL) {
			if (showprompt)
				puts("] ");

			int len = get_line(&buffer, get_line_cookie);
			if (len < 0)
				break;
			if (len == 0)
				continue;
		} else {
			buffer = continuebuffer;
		}

//		dprintf("line = '%s'\n", buffer);

		/* tokenize the line */
		int argc = tokenize_command(buffer, &continuebuffer, outbuf, outbuflen, args, 16);
		if (argc < 0) {
			if (showprompt)
				printf("syntax error\n");
			continue;
		} else if (argc == 0) {
			continue;
		}

//		dprintf("after tokenize: argc %d\n", argc);
//		for (int i = 0; i < argc; i++)
//			dprintf("%d: '%s'\n", i, args[i].str);

		/* convert the args */
		convert_args(argc, args);

		/* try to match the command */
		const cmd *command = match_command(args[0].str);
		if (!command) {
			if (showprompt)
				printf("command not found\n");
			continue;
		}

		if (!locked)
			mutex_acquire(command_lock);

		abort_script = false;
		lastresult = command->cmd_callback(argc, args);

#if WITH_LIB_ENV
		if ((env_get_bool("reportresult", &report_result, false) >= 0) &&
			(report_result))
		{
			if (lastresult < 0)
				printf("FAIL %d\n", lastresult);
			else
				printf("PASS %d\n", lastresult);
		}
#endif

#if WITH_LIB_ENV
		// stuff the result in an environment var
		env_set_int("?", lastresult, true);
#endif

		// someone must have aborted the current script
		if (abort_script)
			exit = true;
		abort_script = false;

		if (!locked)
			mutex_release(command_lock);
	}

	free(outbuf);
}
Beispiel #15
0
void process_command (void)
{
    uint8_t num_tokens = tokenize_command();
    
    if (num_tokens == 0)  // no commands
        return;
    
    /*
    for (uint8_t i = 0; i < num_tokens; i++)
    {
        m_usb_tx_char ('\t');
        
        for (char *ptr = command_tokens[i]; *ptr != '\0'; ptr++)
            m_usb_tx_char (*ptr);
        
        printf ("\n");
    }
    */
    
    if (strcmp (command_tokens[0], "help") == 0)
        printf ("Commands: ls, cd, print, mkdir, rmdir, write, append, edit, keycode\r\n");
    else if (strcmp (command_tokens[0], "ls") == 0)
    {
        if (num_tokens > 1)
            printf ("ls does not take any arguments\r\n");
        else
            ls();
    }
    else if (strcmp (command_tokens[0], "cd") == 0)
    {
        if (num_tokens != 2)
        {
            printf ("cd requires one argument (the destination directory)\r\n");
            return;
        }
        
        if (!m_sd_push (command_tokens[1]))
            printf ("error entering ");
        else
            printf ("now in ");
        
        for (char *c = command_tokens[1]; *c != '\0'; c++)
            putchar (*c);
        printf ("\r\n");
    }
    else if (strcmp (command_tokens[0], "print") == 0)
    {
        if (num_tokens != 2)
        {
            printf ("print requires one argument (the file to print)\r\n");
            return;
        }
        
        printFile (command_tokens[1]);
    }
    else if (strcmp (command_tokens[0], "mkdir") == 0)
    {
        if (num_tokens != 2)
        {
            printf ("mkdir requires one argument (the directory to create)\r\n");
            return;
        }
        
        if (!m_sd_mkdir (command_tokens[1]))
        {
            printf ("error creating directory ");
        }
        else
        {
            printf ("successfully created directory ");
            m_sd_commit();
        }
        
        for (char *c = command_tokens[1]; *c != '\0'; c++)
            putchar (*c);
        printf ("\r\n");
    }
    else if (strcmp (command_tokens[0], "rmdir") == 0)
    {
        if (num_tokens != 2)
        {
            printf ("rmdir requires one argument (the directory to delete)\n");
            return;
        }
        
        if (!m_sd_rmdir (command_tokens[1]))
        {
            printf ("error deleting directory ");
        }
        else
        {
            printf ("successfully deleted directory ");
            m_sd_commit();
        }
        
        for (char *c = command_tokens[1]; *c != '\0'; c++)
            putchar (*c);
        printf ("\r\n");
    }
    else if (strcmp (command_tokens[0], "write") == 0)
    {
        if (num_tokens < 3)
        {
            printf ("write requires a filename, followed by the data to write\r\n");
            return;
        }
        
        writeToFile (command_tokens[1],
                     CREATE_FILE,
                     command_ptr - command_tokens[2],
                     (uint8_t*)command_tokens[2]);
    }
    else if (strcmp (command_tokens[0], "append") == 0)
    {
        if (num_tokens < 3)
        {
            printf ("append requires a filename, followed by the data to write\r\n");
            return;
        }
        
        writeToFile (command_tokens[1],
                     APPEND_FILE,
                     command_ptr - command_tokens[2],
                     (uint8_t*)command_tokens[2]);
    }
    else if (strcmp (command_tokens[0], "edit") == 0)
    {
        if (num_tokens < 2)
        {
            printf ("edit requires a filename\r\n");
            return;
        }
        
        uint8_t fid = 255;
        if (!m_sd_open_file (command_tokens[1], APPEND_FILE, &fid))
        {  // if opening the file in r/w mode failed
            if (m_sd_error_code == ERROR_FAT32_NOT_FOUND)
            {  // if the reason was because the file doesn't exist, try creating it
                m_sd_open_file (command_tokens[1], CREATE_FILE, &fid);
            }
        }
        
        if (fid == 255)
        {  // the file is still not open
            printf ("Couldn't open/create file ");
            for (char *c = command_tokens[1]; *c != '\0'; c++)
                putchar (*c);
            printf ("\r\n");
            return;
        }
        
        edit (fid, command_tokens[1]);
        
        if (!m_sd_close_file (fid))
        {
            printf ("Error closing file!  Error code %d\r\n", m_sd_error_code);
        }
    }
    else if (strcmp (command_tokens[0], "keycode") == 0)
    {  // print the ASCII number of the pressed keys, CTRL-C exits
        keycodes();
    }
    else
    {
        printf ("unknown command\r\n");
    }
}