245 lines
8.8 KiB
C
245 lines
8.8 KiB
C
|
/* PIKA - Photo and Image Kooker Application
|
||
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||
|
*
|
||
|
* Original copyright, applying to most contents (license remains unchanged):
|
||
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||
|
*
|
||
|
* This program 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.
|
||
|
*
|
||
|
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
#include "config.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <libpika/pika.h>
|
||
|
|
||
|
#include "script-fu-server.h"
|
||
|
|
||
|
#include "libscriptfu/script-fu-lib.h"
|
||
|
#include "libscriptfu/script-fu-intl.h"
|
||
|
|
||
|
|
||
|
#define SCRIPT_FU_SERVER_TYPE (script_fu_server_get_type ())
|
||
|
G_DECLARE_FINAL_TYPE (ScriptFuServer, script_fu_server, SCRIPT, FU_SERVER, PikaPlugIn)
|
||
|
|
||
|
struct _ScriptFuServer
|
||
|
{
|
||
|
PikaPlugIn parent_instance;
|
||
|
};
|
||
|
|
||
|
static GList * script_fu_server_query_procedures (PikaPlugIn *plug_in);
|
||
|
static PikaProcedure * script_fu_server_create_procedure (PikaPlugIn *plug_in,
|
||
|
const gchar *name);
|
||
|
|
||
|
static PikaValueArray * script_fu_server_outer_run (PikaProcedure *procedure,
|
||
|
const PikaValueArray *args,
|
||
|
gpointer run_data);
|
||
|
static void script_fu_server_run_init (PikaProcedure *procedure,
|
||
|
PikaRunMode run_mode);
|
||
|
|
||
|
|
||
|
G_DEFINE_TYPE (ScriptFuServer, script_fu_server, PIKA_TYPE_PLUG_IN)
|
||
|
|
||
|
PIKA_MAIN (SCRIPT_FU_SERVER_TYPE)
|
||
|
DEFINE_STD_SET_I18N
|
||
|
|
||
|
|
||
|
static void
|
||
|
script_fu_server_class_init (ScriptFuServerClass *klass)
|
||
|
{
|
||
|
PikaPlugInClass *plug_in_class = PIKA_PLUG_IN_CLASS (klass);
|
||
|
|
||
|
plug_in_class->query_procedures = script_fu_server_query_procedures;
|
||
|
plug_in_class->create_procedure = script_fu_server_create_procedure;
|
||
|
plug_in_class->set_i18n = STD_SET_I18N;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
script_fu_server_init (ScriptFuServer *script_fu_server)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static GList *
|
||
|
script_fu_server_query_procedures (PikaPlugIn *plug_in)
|
||
|
{
|
||
|
GList *list = NULL;
|
||
|
|
||
|
list = g_list_append (list, g_strdup ("plug-in-script-fu-server"));
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
static PikaProcedure *
|
||
|
script_fu_server_create_procedure (PikaPlugIn *plug_in,
|
||
|
const gchar *name)
|
||
|
{
|
||
|
PikaProcedure *procedure = NULL;
|
||
|
|
||
|
/* The run func script_fu_server_outer_run is defined in this source file. */
|
||
|
procedure = pika_procedure_new (plug_in, name,
|
||
|
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||
|
script_fu_server_outer_run, NULL, NULL);
|
||
|
|
||
|
pika_procedure_set_menu_label (procedure, _("_Start Server..."));
|
||
|
pika_procedure_add_menu_path (procedure,
|
||
|
"<Image>/Filters/Development/Script-Fu");
|
||
|
|
||
|
pika_procedure_set_documentation (procedure,
|
||
|
_("Server for remote Script-Fu "
|
||
|
"operation"),
|
||
|
"Provides a server for remote "
|
||
|
"script-fu operation. NOTE that for "
|
||
|
"security reasons this procedure's "
|
||
|
"API was changed in an incompatible "
|
||
|
"way since PIKA 2.8.12. You now have "
|
||
|
"to pass the IP to listen on as "
|
||
|
"first parameter. Calling this "
|
||
|
"procedure with the old API will "
|
||
|
"fail on purpose.",
|
||
|
name);
|
||
|
pika_procedure_set_attribution (procedure,
|
||
|
"Spencer Kimball & Peter Mattis",
|
||
|
"Spencer Kimball & Peter Mattis",
|
||
|
"1997");
|
||
|
|
||
|
PIKA_PROC_ARG_ENUM (procedure, "run-mode",
|
||
|
"Run mode",
|
||
|
"The run mode",
|
||
|
PIKA_TYPE_RUN_MODE,
|
||
|
PIKA_RUN_INTERACTIVE,
|
||
|
G_PARAM_READWRITE);
|
||
|
|
||
|
PIKA_PROC_ARG_STRING (procedure, "ip",
|
||
|
"IP",
|
||
|
"The IP on which to listen for requests",
|
||
|
NULL,
|
||
|
G_PARAM_READWRITE);
|
||
|
|
||
|
PIKA_PROC_ARG_INT (procedure, "port",
|
||
|
"Port",
|
||
|
"The port on which to listen for requests",
|
||
|
0, G_MAXINT, 0,
|
||
|
G_PARAM_READWRITE);
|
||
|
|
||
|
/* FUTURE: PIKA_PROC_ARG_FILE, but little benefit, need change script-fu-server.c */
|
||
|
PIKA_PROC_ARG_STRING (procedure, "logfile",
|
||
|
"Log File",
|
||
|
"The file to log activity to",
|
||
|
NULL,
|
||
|
G_PARAM_READWRITE);
|
||
|
|
||
|
return procedure;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Test cases:
|
||
|
*
|
||
|
* Normal starting is from PIKA GUI: "Filters>Development>Script-Fu>Start server...""
|
||
|
* Expect a dialog to enter IP, etc.
|
||
|
* Expect a console msg: "ScriptFu server: initialized and listening...""
|
||
|
*
|
||
|
* Does not have settings. After the above,
|
||
|
* Expect "Filters>Repeat Last" and "Reshow Last" to be disabled (greyed out)
|
||
|
*
|
||
|
* Execute the server from headless PIKA:
|
||
|
* pika -i --batch-interpreter='plug-in-script-fu-eval'
|
||
|
" -c '(plug-in-script-fu-server 1 "127.0.0.1" 10008 "/tmp/pika-log")'
|
||
|
*
|
||
|
* Execute the binary from command line fails with:
|
||
|
* "script-fu-server is a PIKA plug-in and must be run by PIKA to be used"
|
||
|
*
|
||
|
* The PDB procedure plug-in-script-fu-server CAN be called from another procedure
|
||
|
* (but shouldn't be.)
|
||
|
* Expect plug-in-script-fu-server to never return
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* ScriptFu Server listens and responds to clients.
|
||
|
* The server responds with a success indication,
|
||
|
* and a string representation of the result
|
||
|
* (a representation in Lisp, human-readable but also interpretable.)
|
||
|
* A client may also expect side-effects, e.g. on images and image files.
|
||
|
*
|
||
|
* The server has its own logging.
|
||
|
* Its logging defaults to stdout, but optionally to a file.
|
||
|
* The server logs errors in interpretation of the stream from the client.
|
||
|
*
|
||
|
* A client may quit the server by eval "(pika-quit)"
|
||
|
* Otherwise, the server blocks on IO from the client.
|
||
|
*
|
||
|
* A server that dies leaves the client with a broken connection,
|
||
|
* but does not affect extension-script-fu.
|
||
|
*
|
||
|
* A server is a child process of a PIKA process.
|
||
|
* Quitting or killing the parent process also kills the server.
|
||
|
*/
|
||
|
static PikaValueArray *
|
||
|
script_fu_server_outer_run (PikaProcedure *procedure,
|
||
|
const PikaValueArray *args,
|
||
|
gpointer run_data)
|
||
|
{
|
||
|
PikaValueArray *return_vals = NULL;
|
||
|
|
||
|
if (pika_value_array_length (args) > 0)
|
||
|
script_fu_server_run_init (procedure, PIKA_VALUES_GET_ENUM (args, 0));
|
||
|
else
|
||
|
script_fu_server_run_init (procedure, PIKA_RUN_NONINTERACTIVE);
|
||
|
|
||
|
/* Remind any users watching the console. */
|
||
|
g_debug ("Starting. Further logging by server might be to a log file.");
|
||
|
|
||
|
/*
|
||
|
* Call the inner run func, defined in script-fu-server.c
|
||
|
* !!! This does not return unless a client evals "(pika-quit)"
|
||
|
*/
|
||
|
return_vals = script_fu_server_run (procedure, args);
|
||
|
|
||
|
/*
|
||
|
* The server returns SUCCESS but no other values (to the caller)
|
||
|
* if it was quit properly.
|
||
|
* The server also returns ERROR if it can't start properly.
|
||
|
*/
|
||
|
g_assert (return_vals != NULL);
|
||
|
return return_vals;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The server is just the interpreter.
|
||
|
* It does not register any scripts as TEMPORARY procs.
|
||
|
* extension-script-fu should also be running, to register its TEMPORARY procs
|
||
|
* (those defined by .scm files in /scripts)
|
||
|
* in the PDB, and to execute the TEMPORARY PDB procs.
|
||
|
*
|
||
|
* We do load initialization and compatibility scripts.
|
||
|
*/
|
||
|
static void
|
||
|
script_fu_server_run_init (PikaProcedure *procedure,
|
||
|
PikaRunMode run_mode)
|
||
|
{
|
||
|
GList *path;
|
||
|
|
||
|
/*
|
||
|
* Non-null path so we load init and compat scripts
|
||
|
* which are jumbled in same dir as TEMPORARY procedure scripts.
|
||
|
*/
|
||
|
path = script_fu_search_path ();
|
||
|
|
||
|
/* Init the interpreter, not allow register scripts */
|
||
|
script_fu_init_embedded_interpreter (path, FALSE, run_mode);
|
||
|
|
||
|
g_list_free_full (path, (GDestroyNotify) g_object_unref);
|
||
|
}
|