Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Source for shell plugin
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include "shell.h"
11 : #include <errno.h>
12 : #include <kdberrors.h>
13 : #include <kdbhelper.h>
14 : #include <stdio.h>
15 : #include <stdlib.h>
16 : #include <sys/types.h>
17 : #include <sys/wait.h>
18 : #include <unistd.h>
19 :
20 :
21 2 : static int executeCommand (const char * cmdline)
22 : {
23 : char * cmd[4];
24 2 : cmd[0] = "/bin/sh";
25 2 : cmd[1] = "-c";
26 2 : cmd[2] = (char *) cmdline;
27 2 : cmd[3] = NULL;
28 :
29 2 : pid_t pid = fork ();
30 2 : if (pid == 0)
31 : {
32 0 : return execv ("/bin/sh", cmd);
33 : }
34 2 : else if (pid > 0)
35 : {
36 : int status;
37 2 : wait (&status);
38 2 : return WEXITSTATUS (status);
39 : }
40 : else
41 : {
42 : return -1;
43 : }
44 : }
45 :
46 32 : int elektraShellGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
47 : {
48 32 : if (!elektraStrCmp (keyName (parentKey), "system/elektra/modules/shell"))
49 : {
50 31 : KeySet * contract =
51 31 : ksNew (30, keyNew ("system/elektra/modules/shell", KEY_VALUE, "shell plugin waits for your orders", KEY_END),
52 : keyNew ("system/elektra/modules/shell/exports", KEY_END),
53 : keyNew ("system/elektra/modules/shell/exports/get", KEY_FUNC, elektraShellGet, KEY_END),
54 : keyNew ("system/elektra/modules/shell/exports/set", KEY_FUNC, elektraShellSet, KEY_END),
55 : keyNew ("system/elektra/modules/shell/exports/error", KEY_FUNC, elektraShellError, KEY_END),
56 : #include ELEKTRA_README
57 : keyNew ("system/elektra/modules/shell/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END);
58 31 : ksAppend (returned, contract);
59 31 : ksDel (contract);
60 :
61 31 : return 1; // success
62 : }
63 1 : KeySet * config = elektraPluginGetConfig (handle);
64 1 : Key * cmdKey = ksLookupByName (config, "/execute/get", KDB_O_NONE);
65 1 : Key * expectedReturnKey = ksLookupByName (config, "/execute/get/return", KDB_O_NONE);
66 1 : if (cmdKey == NULL)
67 : return 1;
68 : else
69 : {
70 0 : int retVal = executeCommand (keyString (cmdKey));
71 0 : if (retVal == -1)
72 : {
73 0 : ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
74 0 : return -1;
75 : }
76 0 : else if (expectedReturnKey)
77 : {
78 0 : if (atoi (keyString (expectedReturnKey)) != retVal)
79 : {
80 0 : ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
81 : "Return value of '%s' doesn't match expected exit. Reason: %s",
82 : keyString (cmdKey), keyString (expectedReturnKey));
83 0 : return -1;
84 : }
85 : }
86 : }
87 : return 1; // success
88 : }
89 :
90 2 : int elektraShellSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey)
91 : {
92 2 : KeySet * config = elektraPluginGetConfig (handle);
93 2 : Key * cmdKey = ksLookupByName (config, "/execute/set", KDB_O_NONE);
94 2 : Key * expectedReturnKey = ksLookupByName (config, "/execute/set/return", KDB_O_NONE);
95 2 : if (cmdKey == NULL)
96 : return 1;
97 : else
98 : {
99 2 : int retVal = executeCommand (keyString (cmdKey));
100 2 : if (retVal == -1)
101 : {
102 0 : ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
103 0 : return -1;
104 : }
105 2 : else if (expectedReturnKey)
106 : {
107 0 : if (atoi (keyString (expectedReturnKey)) != retVal)
108 : {
109 0 : ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
110 : "Return value of '%s' doesn't match expected exit. Reason: %s",
111 : keyString (cmdKey), keyString (expectedReturnKey));
112 0 : return -1;
113 : }
114 : }
115 : }
116 : return 1; // success
117 : }
118 :
119 0 : int elektraShellError (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey)
120 : {
121 0 : KeySet * config = elektraPluginGetConfig (handle);
122 0 : Key * cmdKey = ksLookupByName (config, "/execute/error", KDB_O_NONE);
123 0 : Key * expectedReturnKey = ksLookupByName (config, "/execute/error/return", KDB_O_NONE);
124 0 : if (cmdKey == NULL)
125 : return 1;
126 : else
127 : {
128 0 : int retVal = executeCommand (keyString (cmdKey));
129 0 : if (retVal == -1)
130 : {
131 0 : ELEKTRA_SET_RESOURCE_ERRORF (parentKey, "Launching childprocess failed. Reason: %s", strerror (errno));
132 0 : return -1;
133 : }
134 0 : else if (expectedReturnKey)
135 : {
136 0 : if (atoi (keyString (expectedReturnKey)) != retVal)
137 : {
138 0 : ELEKTRA_SET_PLUGIN_MISBEHAVIOR_ERRORF (parentKey,
139 : "Return value of '%s' doesn't match expected exit. Reason: %s",
140 : keyString (cmdKey), keyString (expectedReturnKey));
141 0 : return -1;
142 : }
143 : }
144 : }
145 : return 1; // success
146 : }
147 :
148 55 : Plugin * ELEKTRA_PLUGIN_EXPORT
149 : {
150 55 : return elektraPluginExport ("shell", ELEKTRA_PLUGIN_GET, &elektraShellGet, ELEKTRA_PLUGIN_SET, &elektraShellSet,
151 : ELEKTRA_PLUGIN_ERROR, &elektraShellError, ELEKTRA_PLUGIN_END);
152 : }
|