mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-07-17 16:34:10 +00:00
Add dispatcher program.
Invoke like dindexer <action> a b c and it will exec ACTIONS_PATH/dindexer-<action> a b c or ACTIONS_PATH/<action>/dindexer-<action> a b c
This commit is contained in:
parent
fca9b94afd
commit
8708ef9503
6 changed files with 310 additions and 0 deletions
|
@ -4,6 +4,7 @@ project("${bare_name}-if" VERSION 0.1.2 LANGUAGES CXX C)
|
||||||
|
|
||||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||||
option(DINDEXER_DEBUG_CFG_FILE "Enable to set the config file path to the build path" OFF)
|
option(DINDEXER_DEBUG_CFG_FILE "Enable to set the config file path to the build path" OFF)
|
||||||
|
set(ACTIONS_PATH "${CMAKE_CURRENT_BINARY_DIR}/src" CACHE STRING "Actions search path")
|
||||||
set(PROJECT_VERSION_BETA "1")
|
set(PROJECT_VERSION_BETA "1")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")
|
||||||
|
@ -24,6 +25,8 @@ find_package(YamlCpp 0.5.1 REQUIRED)
|
||||||
add_library(${PROJECT_NAME} INTERFACE)
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
add_library(${bare_name}-inc INTERFACE)
|
add_library(${bare_name}-inc INTERFACE)
|
||||||
|
|
||||||
|
message(STATUS "Actions search path set to: \"${ACTIONS_PATH}\"")
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"${PROJECT_SOURCE_DIR}/src/${bare_name}Config.h.in"
|
"${PROJECT_SOURCE_DIR}/src/${bare_name}Config.h.in"
|
||||||
"${PROJECT_BINARY_DIR}/${bare_name}Config.h"
|
"${PROJECT_BINARY_DIR}/${bare_name}Config.h"
|
||||||
|
@ -42,6 +45,7 @@ target_include_directories(${bare_name}-inc
|
||||||
|
|
||||||
add_subdirectory(src/update)
|
add_subdirectory(src/update)
|
||||||
add_subdirectory(src/pq)
|
add_subdirectory(src/pq)
|
||||||
|
add_subdirectory(src/main)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
INTERFACE ${PostgreSQL_LIBRARIES}
|
INTERFACE ${PostgreSQL_LIBRARIES}
|
||||||
|
|
|
@ -24,5 +24,7 @@
|
||||||
#define VERSION_BETA @PROJECT_VERSION_BETA@
|
#define VERSION_BETA @PROJECT_VERSION_BETA@
|
||||||
#define VERSION_PATCH @PROJECT_VERSION_PATCH@
|
#define VERSION_PATCH @PROJECT_VERSION_PATCH@
|
||||||
#define CONFIG_FILE_PATH "@DINDEXER_CONFIG_FILE@"
|
#define CONFIG_FILE_PATH "@DINDEXER_CONFIG_FILE@"
|
||||||
|
#define ACTIONS_SEARCH_PATH "@ACTIONS_PATH@"
|
||||||
|
#define ACTION_PREFIX "@bare_name@-"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
14
src/main/CMakeLists.txt
Normal file
14
src/main/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
project(${bare_name} C)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME}
|
||||||
|
main.c
|
||||||
|
findactions.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME}
|
||||||
|
PRIVATE ${CMAKE_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE ${bare_name}-inc
|
||||||
|
)
|
132
src/main/findactions.c
Normal file
132
src/main/findactions.c
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of "dindexer".
|
||||||
|
*
|
||||||
|
* "dindexer" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "dindexer" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iso646.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "dindexerConfig.h"
|
||||||
|
#include "helpers/lengthof.h"
|
||||||
|
|
||||||
|
typedef struct ActionListStruct {
|
||||||
|
char** list;
|
||||||
|
size_t count;
|
||||||
|
size_t used;
|
||||||
|
} ActionList;
|
||||||
|
|
||||||
|
static void increase_actionlist ( const char* parName, ActionList* parList );
|
||||||
|
static void push_action ( const char* parName, ActionList* parList );
|
||||||
|
static void foreach_dir ( void(*parAction)(const char*, ActionList*), ActionList* parList );
|
||||||
|
|
||||||
|
void find_actions (char*** parOut, size_t* parCount) {
|
||||||
|
ActionList list;
|
||||||
|
|
||||||
|
list.count = 0;
|
||||||
|
foreach_dir(&increase_actionlist, &list);
|
||||||
|
if (0 == list.count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*parOut = (char**)malloc(sizeof(char*) * list.count);
|
||||||
|
list.list = *parOut;
|
||||||
|
list.used = 0;
|
||||||
|
foreach_dir(&push_action, &list);
|
||||||
|
|
||||||
|
*parCount = list.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_actions (char** parActions, size_t parCount) {
|
||||||
|
size_t z;
|
||||||
|
|
||||||
|
for (z = 0; z < parCount; ++z) {
|
||||||
|
free(parActions[z]);
|
||||||
|
}
|
||||||
|
free(parActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreach_dir (void(*parAction)(const char*, ActionList*), ActionList* parList) {
|
||||||
|
DIR* d;
|
||||||
|
struct dirent* dir;
|
||||||
|
size_t z;
|
||||||
|
struct stat st;
|
||||||
|
char* path_buff;
|
||||||
|
size_t path_buff_length;
|
||||||
|
size_t search_path_length;
|
||||||
|
size_t path_buff_curr_length;
|
||||||
|
|
||||||
|
d = opendir(ACTIONS_SEARCH_PATH);
|
||||||
|
if (d) {
|
||||||
|
path_buff_length = lengthof(ACTIONS_SEARCH_PATH) + 512;
|
||||||
|
path_buff = (char*)malloc(path_buff_length);
|
||||||
|
strncpy(path_buff, ACTIONS_SEARCH_PATH, lengthof(ACTIONS_SEARCH_PATH));
|
||||||
|
search_path_length = lengthof(ACTIONS_SEARCH_PATH) - 1;
|
||||||
|
if ('/' != path_buff[search_path_length - 1]) {
|
||||||
|
path_buff[search_path_length] = '/';
|
||||||
|
++search_path_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((dir = readdir(d)) != NULL) {
|
||||||
|
/* Check if current item is . or .. */
|
||||||
|
if (not strcmp(".", dir->d_name) or not strcmp("..", dir->d_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if it's a directory */
|
||||||
|
path_buff_curr_length = search_path_length;
|
||||||
|
strncpy(path_buff + path_buff_curr_length, dir->d_name, path_buff_length - path_buff_curr_length);
|
||||||
|
path_buff_curr_length += strlen(dir->d_name);
|
||||||
|
lstat(path_buff, &st);
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
strncpy(path_buff + path_buff_curr_length, "/", path_buff_length - path_buff_curr_length);
|
||||||
|
++path_buff_curr_length;
|
||||||
|
strncpy(path_buff + path_buff_curr_length, ACTION_PREFIX, path_buff_length - path_buff_curr_length);
|
||||||
|
path_buff_curr_length += lengthof(ACTION_PREFIX) - 1;
|
||||||
|
strncpy(path_buff + path_buff_curr_length, dir->d_name, path_buff_length - path_buff_curr_length);
|
||||||
|
|
||||||
|
if (0 == access(path_buff, 0)) {
|
||||||
|
(*parAction)(path_buff + search_path_length, parList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (0 == strncmp(dir->d_name, ACTION_PREFIX, lengthof(ACTION_PREFIX) - 1)) {
|
||||||
|
(*parAction)(dir->d_name, parList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(path_buff);
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void increase_actionlist (const char* parName, ActionList* parList) {
|
||||||
|
++parList->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void push_action (const char* parName, ActionList* parList) {
|
||||||
|
size_t name_len;
|
||||||
|
|
||||||
|
if (parList->used == parList->count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
name_len = strlen(parName);
|
||||||
|
parList->list[parList->used] = (char*)malloc(1 + name_len);
|
||||||
|
strcpy(parList->list[parList->used], parName);
|
||||||
|
++parList->used;
|
||||||
|
}
|
26
src/main/findactions.h
Normal file
26
src/main/findactions.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of "dindexer".
|
||||||
|
*
|
||||||
|
* "dindexer" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "dindexer" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef id0FE0395F6FD14626A837BD8628E29FED
|
||||||
|
#define id0FE0395F6FD14626A837BD8628E29FED
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void find_actions ( char*** parOut, size_t* parCount );
|
||||||
|
void free_actions ( char** parActions, size_t parCount );
|
||||||
|
|
||||||
|
#endif
|
132
src/main/main.c
Normal file
132
src/main/main.c
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* Copyright 2015, Michele Santullo
|
||||||
|
* This file is part of "dindexer".
|
||||||
|
*
|
||||||
|
* "dindexer" is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* "dindexer" is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with "dindexer". If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iso646.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "dindexerConfig.h"
|
||||||
|
#include "findactions.h"
|
||||||
|
#include "helpers/lengthof.h"
|
||||||
|
|
||||||
|
static size_t foreach_avail_action ( int(*parFunc)(char*, char*), char** parList, size_t parCount, char* parPass );
|
||||||
|
static int printf_stderr ( char* parMsg, char* parUnused );
|
||||||
|
static int same_action ( char* parAction1, char* parAction2 );
|
||||||
|
|
||||||
|
int main (int parArgc, char* parArgv[]) {
|
||||||
|
size_t z;
|
||||||
|
size_t actions_count;
|
||||||
|
char** actions;
|
||||||
|
char* action_path;
|
||||||
|
size_t action_path_length;
|
||||||
|
size_t selected_action;
|
||||||
|
char** argv;
|
||||||
|
|
||||||
|
find_actions(&actions, &actions_count);
|
||||||
|
if (0 == actions_count) {
|
||||||
|
fprintf(stderr, "No actions found in \"%s\"\n", ACTIONS_SEARCH_PATH);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parArgc < 2 or strcmp("-h", parArgv[1]) == 0 or strcmp("--help", parArgv[1]) == 0) {
|
||||||
|
fprintf(stderr, "No action specified. Available actions are:\n");
|
||||||
|
foreach_avail_action(&printf_stderr, actions, actions_count, NULL);
|
||||||
|
free_actions(actions, actions_count);
|
||||||
|
if (parArgc < 2) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_action = foreach_avail_action(&same_action, actions, actions_count, parArgv[1]);
|
||||||
|
|
||||||
|
if (actions_count == selected_action) {
|
||||||
|
fprintf(stderr, "Unrecognized action \"%s\" - available actions are:\n", parArgv[1]);
|
||||||
|
foreach_avail_action(&printf_stderr, actions, actions_count, NULL);
|
||||||
|
free_actions(actions, actions_count);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
action_path_length = lengthof(ACTIONS_SEARCH_PATH) - 1;
|
||||||
|
if (ACTIONS_SEARCH_PATH[lengthof(ACTIONS_SEARCH_PATH) - 2] != '/') {
|
||||||
|
++action_path_length;
|
||||||
|
}
|
||||||
|
action_path_length += strlen(actions[selected_action]);
|
||||||
|
++action_path_length;
|
||||||
|
|
||||||
|
action_path = (char*)malloc(action_path_length);
|
||||||
|
memcpy(action_path, ACTIONS_SEARCH_PATH, lengthof(ACTIONS_SEARCH_PATH) - 1);
|
||||||
|
z = lengthof(ACTIONS_SEARCH_PATH) - 1;
|
||||||
|
if (ACTIONS_SEARCH_PATH[lengthof(ACTIONS_SEARCH_PATH) - 2] != '/') {
|
||||||
|
action_path[lengthof(ACTIONS_SEARCH_PATH) - 1] = '/';
|
||||||
|
++z;
|
||||||
|
}
|
||||||
|
strcpy(action_path + z, actions[selected_action]);
|
||||||
|
|
||||||
|
free_actions(actions, actions_count);
|
||||||
|
|
||||||
|
argv = (char**)malloc(sizeof(char*) * (parArgc - 1 + 1));
|
||||||
|
argv[0] = action_path;
|
||||||
|
for (z = 2; z <= parArgc; ++z) {
|
||||||
|
argv[z - 1] = parArgv[z];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*printf("would call %s\n", action_path);*/
|
||||||
|
execv(action_path, argv);
|
||||||
|
|
||||||
|
/* the program won't get here, but just to be clean... */
|
||||||
|
free(action_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t foreach_avail_action(int(*parFunc)(char*, char*), char** parList, size_t parCount, char* parPass) {
|
||||||
|
size_t z;
|
||||||
|
char* cmd_name_start;
|
||||||
|
int stop;
|
||||||
|
|
||||||
|
for (z = 0; z < parCount; ++z) {
|
||||||
|
cmd_name_start = strchr(parList[z], '/');
|
||||||
|
if (not cmd_name_start) {
|
||||||
|
cmd_name_start = parList[z];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++cmd_name_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop = (*parFunc)(cmd_name_start + lengthof(ACTION_PREFIX) - 1, parPass);
|
||||||
|
if (stop) {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int printf_stderr (char* parMsg, char* parUnused) {
|
||||||
|
fprintf(stderr, "\t%s\n", parMsg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int same_action (char* parAction1, char* parAction2) {
|
||||||
|
if (0 == strcmp(parAction1, parAction2)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue