MIDAS
Loading...
Searching...
No Matches
mhttpd.cxx File Reference
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <algorithm>
#include <thread>
#include <deque>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include "midas.h"
#include "msystem.h"
#include "mxml.h"
#include "odbxx.h"
#include "mstrlcpy.h"
#include "mgd.h"
#include "history.h"
#include "mjsonrpc.h"
#include "mvodb.h"
Include dependency graph for mhttpd.cxx:

Go to the source code of this file.

Classes

class  Attachment
 
struct  MimetypeTableEntry
 
class  RequestTrace
 
class  RequestTraceBuf
 
class  Return
 
class  Param
 
struct  search_data
 
struct  CGIF_LABEL
 
struct  CGIF_BAR
 
struct  HistoryData
 
struct  HistVar
 
struct  HistPlot
 
struct  Cookies
 
struct  AuthEntry
 
class  Auth
 

Macros

#define DEFAULT_REFRESH   60
 
#define MAX_GROUPS   32
 
#define MAX_VARS   100
 
#define HTTP_ENCODING   "UTF-8"
 
#define WEB_BUFFER_SIZE   (6*1024*1024)
 
#define MAX_PARAM   500
 
#define PARAM_LENGTH   256
 
#define TEXT_SIZE   50000
 
#define LN10   2.302585094
 
#define LOG2   0.301029996
 
#define LOG5   0.698970005
 
#define ALLOC(t, n)   (t*)calloc(sizeof(t),(n))
 
#define DELETE(x)   if (x) { free(x); (x)=NULL; }
 
#define DELETEA(x, n)   if (x) { for (int i=0; i<(n); i++) { free((x)[i]); (x)[i]=NULL; }; DELETE(x); }
 
#define STRDUP(x)   strdup(x)
 
#define READ_HISTORY_DATA   0x1
 
#define READ_HISTORY_RUNMARKER   0x2
 
#define READ_HISTORY_LAST_WRITTEN   0x4
 
#define RESPONSE_SENT   1
 
#define RESPONSE_QUEUED   2
 
#define RESPONSE_501   3
 

Functions

static std::string toString (int i)
 
static std::string GetMimetype (const std::string &ext)
 
static void SaveMimetypes (MVOdb *odb)
 
void show_hist_page (MVOdb *odb, Param *p, Return *r, const char *dec_path, char *buffer, int *buffer_size, int refresh)
 
int vaxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double ymin, double ymax, BOOL logaxis)
 
void haxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double xmin, double xmax)
 
void get_elog_url (char *url, int len)
 
void show_header (Return *r, const char *title, const char *method, const char *path, int refresh)
 
void show_navigation_bar (Return *r, const char *cur_page)
 
charstristr (const char *str, const char *pattern)
 
static double GetTimeSec ()
 
const charmhttpd_revision (void)
 
static std::string UrlDecode (const char *p)
 
static void urlDecode (char *p)
 
static void urlEncode (char *ps, int ps_size)
 
static std::string urlEncode (const char *text)
 
std::vector< std::string > get_resource_paths ()
 
bool open_resource_file (const char *filename, std::string *ppath, FILE **pfp)
 
std::string get_content_type (const char *filename)
 
bool send_fp (Return *r, const std::string &path, FILE *fp)
 
bool send_file (Return *r, const std::string &path, bool generate_404=true)
 
bool send_resource (Return *r, const std::string &name, bool generate_404=true)
 
INT sendmail (const char *from_host, const char *smtp_host, const char *from, const char *to, const char *subject, const char *text)
 
void redirect (Return *r, const char *path)
 
void redirect_307 (Return *r, const char *path)
 
void redirect2 (Return *r, const char *path)
 
INT search_callback (HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
 
void show_help_page (Return *r, const char *dec_path)
 
void show_text_header (Return *r)
 
void show_error (Return *r, const char *error)
 
void show_error_404 (Return *r, const char *error)
 
void check_obsolete_odb (HNDLE hDB, const char *odb_path)
 
void init_menu_buttons (MVOdb *odb)
 
void init_mhttpd_odb (MVOdb *odb)
 
void init_elog_odb ()
 
void strencode (Return *r, const char *text)
 
std::string strencode2 (const char *text)
 
void strencode3 (Return *r, const char *text)
 
void strencode4 (Return *r, const char *text)
 
void gen_odb_attachment (Return *r, const char *path, std::string &bout)
 
void submit_elog (MVOdb *odb, Param *pp, Return *r, Attachment *a)
 
void show_elog_attachment (Param *p, Return *r, const char *path)
 
BOOL is_editable (char *eq_name, char *var_name)
 
void show_eqtable_page (Param *pp, Return *r, int refresh)
 
charfind_odb_tag (char *p, char *path, char *format, int *edit, char *type, char *pwd, char *tail)
 
void show_odb_tag (Param *pp, Return *r, const char *path, const char *keypath1, const char *format, int n_var, int edit, char *type, char *pwd, char *tail)
 
int evaluate_src (char *key, char *src, double *fvalue)
 
std::string add_custom_path (const std::string &filename)
 
void show_custom_file (Return *r, const char *name)
 
void show_custom_gif (Return *rr, const char *name)
 
void do_jrpc_rev0 (Param *p, Return *r)
 
void do_jrpc_rev1 (Param *p, Return *r)
 
void do_jrpc (Param *p, Return *r)
 
void output_key (Param *p, Return *r, HNDLE hkey, int index, const char *format)
 
bool starts_with (const std::string &s1, const char *s2)
 
void javascript_commands (Param *p, Return *r, const char *cookie_cpwd)
 
void show_custom_page (Param *pp, Return *r, const char *cookie_cpwd)
 
static void show_cnaf_page (Param *p, Return *rr)
 
void show_password_page (Return *r, const char *dec_path, const char *password)
 
BOOL check_web_password (Return *r, HNDLE hDB, const char *dec_path, const char *password, const char *redir)
 
void show_odb_page (Param *pp, Return *r, const char *dec_path, int write_access)
 
void show_set_page (Param *pp, Return *r, const char *group, int index, const char *value)
 
void show_find_page (Return *r, const char *value)
 
void sec_to_label (char *result, int sec, int base, int force_date)
 
void taxis (gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int xr, int minor, int major, int text, int label, int grid, double xmin, double xmax)
 
int time_to_sec (const char *str)
 
time_t string_to_time (const char *str)
 
std::string time_to_string (time_t t)
 
static void history_watch_callback (HNDLE hDB, HNDLE hKey, int index, void *info)
 
static MidasHistoryInterfaceget_history (bool reset=false)
 
static void LoadHistPlotFromOdb (MVOdb *odb, HistPlot *hp, const char *group, const char *panel)
 
int read_history (const HistPlot &hp, int index, int flags, time_t tstart, time_t tend, time_t scale, HistoryData *data)
 
int get_hist_last_written (MVOdb *odb, const char *group, const char *panel, time_t endtime, int index, int want_all, time_t *plastwritten)
 
void generate_hist_graph (MVOdb *odb, Return *rr, const char *hgroup, const char *hpanel, char *buffer, int *buffer_size, int width, int height, time_t xendtime, int scale, int index, int labels, const char *bgcolor, const char *fgcolor, const char *gridcolor)
 
time_t mktime_with_dst (const struct tm *ptms)
 
static std::string add_param_to_url (const char *name, const char *value)
 
void show_query_page (Param *p, Return *r)
 
static int cmp_names (const void *a, const void *b)
 
const bool cmp_events (const std::string &a, const std::string &b)
 
const bool cmp_events1 (const std::string &a, const std::string &b)
 
const bool cmp_tags (const TAG &a, const TAG &b)
 
int xdb_get_data_index (HNDLE hDB, const char *str, void *value, int size, int index, int tid)
 
static int xdb_find_key (HNDLE hDB, HNDLE dir, const char *str, HNDLE *hKey, int tid, int size)
 
static bool cmp_vars (const HistVar &a, const HistVar &b)
 
static void PrintHistPlot (const HistPlot &hp)
 
static std::string NextHistPlotColour (const HistPlot &hp)
 
static int NextHistPlotOrder (const HistPlot &hp)
 
static void SplitEventAndTagNames (std::string var_name, std::string &event_name, std::string &tag_name)
 
static void LoadHistPlotFromParam (HistPlot *hp, Param *p)
 
static void AddHistPlotSelectedParam (HistPlot &hp, Param *p)
 
static void SaveHistPlotToOdb (MVOdb *odb, const HistPlot &hp, const char *group, const char *panel)
 
static void DeleteHistPlotDeleted (HistPlot &hp)
 
static void SortHistPlotVars (HistPlot &hp)
 
void show_hist_config_page (MVOdb *odb, Param *p, Return *r, const char *hgroup, const char *hpanel)
 
void export_hist (MVOdb *odb, Return *r, const char *group, const char *panel, time_t endtime, int scale, int index, int labels)
 
void send_icon (Return *r, const char *icon)
 
void Lock (RequestTrace *t)
 
void Unlock (RequestTrace *t)
 
void interprete (Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
 
void decode_query (Param *pp, const char *query_string)
 
void decode_get (Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
 
void decode_post (Return *rr, const char *header, const char *string, const char *boundary, int length, const Cookies *c, const char *url, RequestTrace *t)
 
INT check_odb_records (MVOdb *odb)
 
void ctrlc_handler (int sig)
 
int try_file_mg (const char *try_dir, const char *filename, std::string &path, FILE **fpp, bool trace)
 
int find_file_mg (const char *filename, std::string &path, FILE **fpp, bool trace)
 
static bool read_passwords (Auth *auth)
 
static void xmg_mkmd5resp (const char *method, size_t method_len, const char *uri, size_t uri_len, const char *ha1, size_t ha1_len, const char *nonce, size_t nonce_len, const char *nc, size_t nc_len, const char *cnonce, size_t cnonce_len, const char *qop, size_t qop_len, char *resp)
 
static int xmg_check_nonce (const char *nonce)
 
static void xmg_http_send_digest_auth_request (struct mg_connection *c, const char *domain)
 
static std::string check_digest_auth (struct http_message *hm, Auth *auth)
 
static std::string mgstr (const mg_str *s)
 
static const std::string find_header_mg (const struct http_message *msg, const char *name)
 
static const std::string find_cookie_mg (const struct http_message *msg, const char *cookie_name)
 
static void handle_event_mg (struct mg_connection *nc, int ev, void *ev_data)
 
void decode_cookies (Cookies *c, const http_message *msg)
 
static int handle_decode_get (struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
 
static int handle_decode_post (struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
 
static int handle_http_get (struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
 
static int handle_http_post (struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
 
static void handle_http_options_cors (struct mg_connection *nc, const http_message *msg, RequestTrace *t)
 
static bool mongoose_passwords_enabled (const struct mg_connection *nc)
 
static void handle_http_message (struct mg_connection *nc, http_message *msg)
 
static MJsonNode * get_http_trace (const MJsonNode *params)
 
static MJsonNode * set_http_trace (const MJsonNode *params)
 
static void add_rpc_functions ()
 
int main (int argc, const char *argv[])
 

Variables

static std::mutex gMutex
 
static MVOdbgOdb = NULL
 
static BOOL elog_mode = FALSE
 
static BOOL history_mode = FALSE
 
static BOOL verbose = FALSE
 
const charmname []
 
static const char default_type_list [20][NAME_LENGTH]
 
static const char default_system_list [20][NAME_LENGTH]
 
const MimetypeTableEntry gMimetypeTable []
 
static MVOdbgMimeTypesOdb = NULL
 
const unsigned char favicon_png []
 
const unsigned char favicon_ico []
 
static int http_trace = 0
 
static RequestTraceBufgTraceBuf = NULL
 
static const charcgif_label_str []
 
static const charcgif_bar_str []
 
static bool gDoSetupHistoryWatch = true
 
static bool gDoReloadHistory = false
 
static MidasHistoryInterfacegMh = NULL
 
static HNDLE gMhkey = 0
 
std::atomic_bool _abort {false}
 
static std::vector< std::string > gAllowedHosts
 
static bool verbose_mg = false
 
static bool trace_mg = false
 
static bool trace_mg_recv = false
 
static bool trace_mg_send = false
 
static AuthgAuthMg = NULL
 

Macro Definition Documentation

◆ ALLOC

#define ALLOC (   t,
  n 
)    (t*)calloc(sizeof(t),(n))

Definition at line 8234 of file mhttpd.cxx.

◆ DEFAULT_REFRESH

#define DEFAULT_REFRESH   60

Definition at line 39 of file mhttpd.cxx.

◆ DELETE

#define DELETE (   x)    if (x) { free(x); (x)=NULL; }

Definition at line 8235 of file mhttpd.cxx.

◆ DELETEA

#define DELETEA (   x,
  n 
)    if (x) { for (int i=0; i<(n); i++) { free((x)[i]); (x)[i]=NULL; }; DELETE(x); }

Definition at line 8236 of file mhttpd.cxx.

◆ HTTP_ENCODING

#define HTTP_ENCODING   "UTF-8"

Definition at line 211 of file mhttpd.cxx.

◆ LN10

#define LN10   2.302585094

Definition at line 7628 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7629 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

Definition at line 7630 of file mhttpd.cxx.

◆ MAX_GROUPS

#define MAX_GROUPS   32

Definition at line 50 of file mhttpd.cxx.

◆ MAX_PARAM

#define MAX_PARAM   500

Definition at line 695 of file mhttpd.cxx.

◆ MAX_VARS

#define MAX_VARS   100

Definition at line 51 of file mhttpd.cxx.

◆ PARAM_LENGTH

#define PARAM_LENGTH   256

Definition at line 696 of file mhttpd.cxx.

◆ READ_HISTORY_DATA

#define READ_HISTORY_DATA   0x1

Definition at line 8320 of file mhttpd.cxx.

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8322 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8321 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14255 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14254 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14253 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

Definition at line 8237 of file mhttpd.cxx.

◆ TEXT_SIZE

#define TEXT_SIZE   50000

Definition at line 697 of file mhttpd.cxx.

◆ WEB_BUFFER_SIZE

#define WEB_BUFFER_SIZE   (6*1024*1024)

Definition at line 509 of file mhttpd.cxx.

Function Documentation

◆ add_custom_path()

std::string add_custom_path ( const std::string &  filename)

Definition at line 3570 of file mhttpd.cxx.

3571{
3572 // do not append custom path to absolute filenames
3573
3574 if (filename[0] == '/')
3575 return filename;
3576 if (filename[0] == DIR_SEPARATOR)
3577 return filename;
3578
3579 HNDLE hDB;
3581
3582 std::string custom_path = "";
3583
3584 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3585
3586 if (status != DB_SUCCESS)
3587 return filename;
3588
3589 if (custom_path.length() < 1)
3590 return filename;
3591
3593 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3594 return filename;
3595 }
3596
3598
3599 std::string full_filename = custom_path;
3600 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3602 full_filename += filename;
3603
3604 return full_filename;
3605}
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3011
#define DB_SUCCESS
Definition midas.h:631
#define MERROR
Definition midas.h:559
std::string ss_replace_env_variables(const std::string &inputPath)
Definition system.cxx:2212
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
Definition odb.cxx:13934
HNDLE hDB
main ODB handle
Definition mana.cxx:207
#define DIR_SEPARATOR
Definition midas.h:193
INT HNDLE
Definition midas.h:132
#define DIR_SEPARATOR_STR
Definition midas.h:194
#define TRUE
Definition midas.h:182
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_param_to_url()

static std::string add_param_to_url ( const char name,
const char value 
)
static

Definition at line 9780 of file mhttpd.cxx.

9781{
9782 std::string s;
9783 s += name; // FIXME: should be URI-encoded
9784 s += "=";
9785 s += value; // FIXME: should be URI-encoded
9786 return s;
9787}
#define name(x)
Definition midas_macro.h:24
double value[100]
Definition odbhist.cxx:42
Here is the caller graph for this function:

◆ add_rpc_functions()

static void add_rpc_functions ( )
static

Definition at line 16202 of file mhttpd.cxx.

16203{
16204 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16205 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16206}
void mjsonrpc_add_handler(const char *method, mjsonrpc_handler_t *handler, bool needs_locking)
static MJsonNode * get_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16175
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16188
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddHistPlotSelectedParam()

static void AddHistPlotSelectedParam ( HistPlot hp,
Param p 
)
static

Definition at line 10377 of file mhttpd.cxx.

10378{
10379 int seln = atoi(p->getparam("seln"));
10380 for (int i=0; i<seln; i++) {
10381 char str[256];
10382 sprintf(str, "sel%d", i);
10383
10384 std::string par = p->getparam(str);
10385 if (par.length() < 1)
10386 continue;
10387
10388 std::string event_name, tag_name;
10389 SplitEventAndTagNames(par, event_name, tag_name);
10390
10391 if (tag_name == "")
10392 continue;
10393
10394 HistVar v;
10395
10396 v.event_name = event_name;
10397 v.tag_name = tag_name;
10400
10401 hp.vars.push_back(v);
10402 }
10403}
const char * getparam(const char *param)
Definition mhttpd.cxx:774
INT i
Definition mdump.cxx:32
static void SplitEventAndTagNames(std::string var_name, std::string &event_name, std::string &tag_name)
Definition mhttpd.cxx:10151
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10116
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10142
char str[256]
Definition odbhist.cxx:33
std::string tag_name
Definition mhttpd.cxx:8327
int order
Definition mhttpd.cxx:8332
std::string colour
Definition mhttpd.cxx:8329
std::string event_name
Definition mhttpd.cxx:8326
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_digest_auth()

static std::string check_digest_auth ( struct http_message hm,
Auth auth 
)
static

Definition at line 13892 of file mhttpd.cxx.

13893{
13894 char expected_response[33];
13895
13896 //printf("HereA!\n");
13897
13898 /* Parse "Authorization:" header, fail fast on parse error */
13899 struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
13900
13901 if (!hdr)
13902 return "";
13903
13904 //printf("HereB!\n");
13905
13906 std::string user = find_var_mg(hdr, "username");
13907 std::string cnonce = find_var_mg(hdr, "cnonce");
13908 std::string response = find_var_mg(hdr, "response");
13909 std::string uri = find_var_mg(hdr, "uri");
13910 std::string qop = find_var_mg(hdr, "qop");
13911 std::string nc = find_var_mg(hdr, "nc");
13912 std::string nonce = find_var_mg(hdr, "nonce");
13913
13914 if (user.length()<1) return "";
13915 if (cnonce.length()<1) return "";
13916 if (response.length()<1) return "";
13917 if (uri.length()<1) return "";
13918 if (qop.length()<1) return "";
13919 if (nc.length()<1) return "";
13920 if (nonce.length()<1) return "";
13921
13922 if (xmg_check_nonce(nonce.c_str()) == 0) return "";
13923 //printf("HereB8!\n");
13924
13925 //printf("HereC!\n");
13926
13927 const char* uri_end = strchr(hm->uri.p, ' ');
13928 if (!uri_end) return "";
13929
13930 size_t uri_length = uri_end - hm->uri.p;
13931
13932 if (uri_length != uri.length())
13933 return "";
13934
13935 int cmp = strncmp(hm->uri.p, uri.c_str(), uri_length);
13936
13937 //printf("check URI: message %d %d [%d] authorization [%s]\n", (int)hm->uri.len, uri_length, cmp, uri);
13938
13939 if (cmp != 0)
13940 return "";
13941
13942 for (unsigned i=0; i<auth->passwords.size(); i++) {
13943 AuthEntry* e = &auth->passwords[i];
13944 if (e->username != user)
13945 continue;
13946 if (e->realm != auth->realm)
13947 continue;
13948 const char* f_ha1 = e->password.c_str();
13949 int uri_len = hm->uri.len;
13950 if (hm->uri.p[uri_len] == '?')
13951 uri_len += hm->query_string.len + 1; // "+1" accounts for the "?" character
13952 xmg_mkmd5resp(hm->method.p, hm->method.len,
13953 hm->uri.p, uri_len,
13954 f_ha1, strlen(f_ha1),
13955 nonce.c_str(), nonce.length(),
13956 nc.c_str(), nc.length(),
13957 cnonce.c_str(), cnonce.length(),
13958 qop.c_str(), qop.length(),
13960 int cmp = strcasecmp(response.c_str(), expected_response);
13961 //printf("digest_auth: expected %s, got %s, cmp %d\n", expected_response, response.c_str(), cmp);
13962 if (cmp == 0) {
13963 return e->username;
13964 }
13965 }
13966
13967 return "";
13968}
struct mg_str * mg_get_http_header(struct http_message *hm, const char *name)
char response[10000]
Definition melog.cxx:90
static void xmg_mkmd5resp(const char *method, size_t method_len, const char *uri, size_t uri_len, const char *ha1, size_t ha1_len, const char *nonce, size_t nonce_len, const char *nc, size_t nc_len, const char *cnonce, size_t cnonce_len, const char *qop, size_t qop_len, char *resp)
Definition mhttpd.cxx:13754
static int xmg_check_nonce(const char *nonce)
Definition mhttpd.cxx:13775
Definition mhttpd.cxx:13716
std::string password
Definition mhttpd.cxx:13719
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_obsolete_odb()

void check_obsolete_odb ( HNDLE  hDB,
const char odb_path 
)

Definition at line 1881 of file mhttpd.cxx.

1882{
1883 HNDLE hKey;
1884 int status = db_find_key(hDB, 0, odb_path, &hKey);
1885 if (status == DB_SUCCESS) {
1886 cm_msg(MERROR, "check_obsolete_odb", "ODB \"%s\" is obsolete, please delete it.", odb_path);
1887 }
1888}
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4079
HNDLE hKey
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_odb_records()

INT check_odb_records ( MVOdb odb)

Definition at line 13389 of file mhttpd.cxx.

13390{
13391 HNDLE hDB, hKeyEq, hKey;
13393 int i, status;
13394 KEY key;
13395
13396 /* check /Runinfo structure */
13398 assert(status == DB_SUCCESS);
13399
13400 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13401 if (status == DB_STRUCT_MISMATCH) {
13402 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13403 if (status == DB_SUCCESS) {
13404 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13405 } else {
13406 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13407 return 0;
13408 }
13409 } else if (status == DB_NO_KEY) {
13410 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13411 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13412 if (status == DB_SUCCESS) {
13413 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13414 } else {
13415 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13416 return 0;
13417 }
13418 } else if (status != DB_SUCCESS) {
13419 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13420 return 0;
13421 }
13422
13423 /* check /Equipment/<name>/Common structures */
13424 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13425 for (i = 0 ;; i++) {
13427 if (!hKey)
13428 break;
13429 db_get_key(hDB, hKey, &key);
13430
13432 if (status == DB_STRUCT_MISMATCH) {
13434 if (status == DB_SUCCESS) {
13435 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13436 } else {
13437 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13438 }
13439 } else if (status != DB_SUCCESS) {
13440 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13441 }
13442 }
13443 }
13444
13445 return CM_SUCCESS;
13446}
#define FALSE
Definition cfortran.h:309
#define CM_SUCCESS
Definition midas.h:582
#define DB_STRUCT_MISMATCH
Definition midas.h:654
#define DB_NO_KEY
Definition midas.h:642
#define MINFO
Definition midas.h:560
std::string strcomb1(const char **list)
Definition odb.cxx:598
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:12972
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5586
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12800
KEY key
Definition mdump.cxx:34
#define EQUIPMENT_COMMON_STR
Definition midas.h:1112
#define RUNINFO_STR(_name)
Definition midas.h:1410
Definition midas.h:1026
char name[NAME_LENGTH]
Definition midas.h:1029
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_web_password()

BOOL check_web_password ( Return r,
HNDLE  hDB,
const char dec_path,
const char password,
const char redir 
)

Definition at line 6736 of file mhttpd.cxx.

6737{
6738 HNDLE hkey;
6739 INT size;
6740 char str[256];
6741
6742 /* check for password */
6743 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
6744 if (hkey) {
6745 size = sizeof(str);
6746 db_get_data(hDB, hkey, str, &size, TID_STRING);
6747 if (strcmp(password, str) == 0)
6748 return TRUE;
6749
6750 /* show web password page */
6751 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6752 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6753 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6754
6755 r->rsprintf("<html><head>\n");
6756 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6757 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6758 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6759 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6760
6761 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6762
6763 /* define hidden fields for current experiment and destination */
6764 if (redir[0])
6765 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", redir);
6766
6767 /*---- page header ----*/
6768 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6769
6770 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6771
6772 if (password[0])
6773 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6774
6775 r->rsprintf
6776 ("<tr><th>Please enter password to obtain write access</tr>\n");
6777 r->rsprintf("<tr><td align=center><input type=password name=wpwd></tr>\n");
6778 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6779
6780 r->rsprintf("</table>\n");
6781
6782 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6783 r->rsprintf("</form>\n");
6784 r->rsprintf("</body></html>\r\n");
6785
6786 return FALSE;
6787 } else
6788 return TRUE;
6789}
void rsprintf(const char *format,...) MATTRPRINTF(2
#define TID_STRING
Definition midas.h:346
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6539
#define HTTP_ENCODING
Definition mhttpd.cxx:211
const char * mhttpd_revision(void)
Definition mhttpd.cxx:834
int INT
Definition midas.h:129
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_events()

const bool cmp_events ( const std::string &  a,
const std::string &  b 
)

Definition at line 10033 of file mhttpd.cxx.

10034{
10035 return cmp_names(a.c_str(), b.c_str()) < 0;
10036}
static int cmp_names(const void *a, const void *b)
Definition mhttpd.cxx:9975
Here is the call graph for this function:

◆ cmp_events1()

const bool cmp_events1 ( const std::string &  a,
const std::string &  b 
)

Definition at line 10038 of file mhttpd.cxx.

10039{
10040 return a < b;
10041}
Here is the caller graph for this function:

◆ cmp_names()

static int cmp_names ( const void a,
const void b 
)
static

Definition at line 9975 of file mhttpd.cxx.

9976{
9977 int i;
9978 const char*sa = (const char*)a;
9979 const char*sb = (const char*)b;
9980
9981 int debug = 0;
9982
9983 // Cannot use strcmp() because it does not know how to compare numerical values, e.g.
9984 // it thinks "111" is smaller than "9"
9985 //return strcmp(sa, sb);
9986
9987 if (debug)
9988 printf("compare [%s] and [%s]\n", sa, sb);
9989
9990 for (i=0; ; i++) {
9991 if (sa[i]==0 && sb[i]==0)
9992 return 0; // both strings have the same length and the same characters
9993
9994 //printf("index %d, char [%c] [%c], isdigit %d %d\n", i, sa[i], sb[i], isdigit(sa[i]), isdigit(sb[i]));
9995
9996 if (isdigit(sa[i]) && isdigit(sb[i])) {
9997 int va = atoi(sa+i);
9998 int vb = atoi(sb+i);
9999
10000 if (debug)
10001 printf("index %d, values %d %d\n", i, va, vb);
10002
10003 if (va < vb)
10004 return -1;
10005 else if (va > vb)
10006 return 1;
10007
10008 // values are equal, skip the the end of the digits, compare any trailing text
10009 continue;
10010 }
10011
10012 if (sa[i]==sb[i]) {
10013 continue;
10014 }
10015
10016 if (debug)
10017 printf("index %d, char [%c] [%c]\n", i, sa[i], sb[i]);
10018
10019 if (sa[i] == 0) // string sa is shorter
10020 return -1;
10021 else if (sb[i] == 0) // string sb is shorter
10022 return 1;
10023
10024 if (sa[i]<sb[i])
10025 return -1;
10026 else
10027 return 1;
10028 }
10029
10030 // NOT REACHED
10031}
BOOL debug
debug printouts
Definition mana.cxx:254
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_tags()

const bool cmp_tags ( const TAG a,
const TAG b 
)

Definition at line 10043 of file mhttpd.cxx.

10044{
10045 return cmp_names(a.name, b.name) < 0;
10046}
char name[NAME_LENGTH]
Definition midas.h:1235
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cmp_vars()

static bool cmp_vars ( const HistVar a,
const HistVar b 
)
static

Definition at line 10101 of file mhttpd.cxx.

10102{
10103 return a.order < b.order;
10104}
Here is the caller graph for this function:

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13453 of file mhttpd.cxx.

13454{
13455 _abort = true;
13456}
std::atomic_bool _abort
Definition mhttpd.cxx:13451
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14206 of file mhttpd.cxx.

14207{
14208 // extract password cookies
14209
14210 char cookie_pwd[256]; // general access password
14211 char cookie_wpwd[256]; // "write mode" password
14212 char cookie_cpwd[256]; // custom page and javascript password
14213
14214 cookie_pwd[0] = 0;
14215 cookie_wpwd[0] = 0;
14216 cookie_cpwd[0] = 0;
14217
14218 std::string s = find_cookie_mg(msg, "midas_pwd");
14219 if (s.length() > 0) {
14220 mstrlcpy(cookie_pwd, s.c_str(), sizeof(cookie_pwd));
14221 cookie_pwd[strcspn(cookie_pwd, " ;\r\n")] = 0;
14222 }
14223
14224 s = find_cookie_mg(msg, "midas_wpwd");
14225 if (s.length()) {
14226 mstrlcpy(cookie_wpwd, s.c_str(), sizeof(cookie_pwd));
14227 cookie_wpwd[strcspn(cookie_wpwd, " ;\r\n")] = 0;
14228 }
14229
14230 s = find_cookie_mg(msg, "cpwd");
14231 if (s.length()) {
14232 mstrlcpy(cookie_cpwd, s.c_str(), sizeof(cookie_pwd));
14233 cookie_cpwd[strcspn(cookie_cpwd, " ;\r\n")] = 0;
14234 }
14235
14236 // extract refresh rate
14237 c->refresh = DEFAULT_REFRESH;
14238 s = find_cookie_mg(msg, "midas_refr");
14239 if (s.length() > 0)
14240 c->refresh = atoi(s.c_str());
14241
14242 // extract equipment expand flag
14243 //c->expand_equipment = 0;
14244 //s = find_cookie_mg(msg, "midas_expeq");
14245 //if (s.length() > 0)
14246 // c->expand_equipment = atoi(s.c_str());
14247
14248 c->cookie_pwd = cookie_pwd;
14249 c->cookie_wpwd = cookie_wpwd;
14250 c->cookie_cpwd = cookie_cpwd;
14251}
#define DEFAULT_REFRESH
Definition mhttpd.cxx:39
static const std::string find_cookie_mg(const struct http_message *msg, const char *cookie_name)
Definition mhttpd.cxx:14154
char c
Definition system.cxx:1310
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_get()

void decode_get ( Return rr,
char string,
const Cookies c,
const char url,
const char query_string,
RequestTrace t 
)

Definition at line 13195 of file mhttpd.cxx.

13196{
13197 char path[256];
13198
13199 //printf("decode_get: string [%s], decode_url %d, url [%s], query_string [%s]\n", string, decode_url, url, query_string);
13200
13201 Param* param = new Param();
13202
13203 param->initparam();
13204
13205 if (url)
13206 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13207 else {
13208 mstrlcpy(path, string + 1, sizeof(path)); /* strip leading '/' */
13209
13210 if (strchr(path, '?'))
13211 *strchr(path, '?') = 0;
13212 }
13213
13214 param->setparam("path", path);
13215
13216 assert(query_string != NULL);
13217
13218 decode_query(param, query_string);
13219
13220 param->setparam("query", query_string);
13221
13222 char dec_path[256];
13223 mstrlcpy(dec_path, path, sizeof(dec_path));
13224
13225 interprete(param, rr, NULL, c, dec_path, t);
13226
13227 param->freeparam();
13228 delete param;
13229}
char param[10][256]
Definition mana.cxx:250
void decode_query(Param *pp, const char *query_string)
Definition mhttpd.cxx:13171
void interprete(Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
Definition mhttpd.cxx:12254
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_post()

void decode_post ( Return rr,
const char header,
const char string,
const char boundary,
int  length,
const Cookies c,
const char url,
RequestTrace t 
)

Definition at line 13233 of file mhttpd.cxx.

13234{
13235 bool debug_decode_post = false;
13236
13237 Param* param = new Param;
13238
13239 param->initparam();
13240
13241 char path[256];
13242
13243 if (url)
13244 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13245 else {
13246 mstrlcpy(path, header + 1, sizeof(path)); /* strip leading '/' */
13247 if (strchr(path, '?'))
13248 *strchr(path, '?') = 0;
13249 if (strchr(path, ' '))
13250 *strchr(path, ' ') = 0;
13251 }
13252 param->setparam("path", path); // undecoded path
13253
13254 Attachment* a = new Attachment;
13255
13256 const char* pinit = string;
13257
13258 /* return if no boundary defined */
13259 if (!boundary[0])
13260 return;
13261
13262 if (strstr(string, boundary))
13263 string = strstr(string, boundary) + strlen(boundary);
13264
13266 printf("decode_post: -->[%s]<--\n", string);
13267
13268 do {
13269 //printf("decode_post: [%s]\n", string);
13270 if (strstr(string, "name=")) {
13271 const char* pitem = strstr(string, "name=") + 5;
13272 if (*pitem == '\"')
13273 pitem++;
13274
13275 //printf("decode_post: pitem [%s]\n", pitem);
13276
13277 if (strncmp(pitem, "attfile", 7) == 0) {
13278 int n = pitem[7] - '1';
13279
13280 char file_name[256];
13281 file_name[0] = 0;
13282
13283 /* evaluate file attachment */
13284 if (strstr(pitem, "filename=")) {
13285 const char* p = strstr(pitem, "filename=") + 9;
13286 if (*p == '\"')
13287 p++;
13288 if (strstr(p, "\r\n\r\n"))
13289 string = strstr(p, "\r\n\r\n") + 4;
13290 else if (strstr(p, "\r\r\n\r\r\n"))
13291 string = strstr(p, "\r\r\n\r\r\n") + 6;
13292
13293 mstrlcpy(file_name, p, sizeof(file_name));
13294
13295 char* pp = file_name;
13296 if (strchr(pp, '\"'))
13297 *strchr(pp, '\"') = 0;
13298
13299 /* set attachment filename */
13300 char str[256];
13301 sprintf(str, "attachment%d", n);
13303 printf("decode_post: [%s] = [%s]\n", str, file_name);
13304 param->setparam(str, file_name); // file_name should be decoded?
13305 }
13306
13307 /* find next boundary */
13308 const char* ptmp = string;
13309 const char* p = NULL;
13310 do {
13311 while (*ptmp != '-')
13312 ptmp++;
13313
13314 p = strstr(ptmp, boundary);
13315 if (p != NULL) {
13316 while (*p == '-')
13317 p--;
13318 if (*p == 10)
13319 p--;
13320 if (*p == 13)
13321 p--;
13322 p++;
13323 break;
13324 } else
13325 ptmp += strlen(ptmp);
13326
13327 } while (TRUE);
13328
13329 /* save pointer to file */
13330 if (file_name[0]) {
13331 size_t size = (POINTER_T) p - (POINTER_T) string;
13332 char* buf = (char*)malloc(size+1);
13333 if (!buf) {
13334 return;
13335 }
13336 memcpy(buf, string, size);
13337 buf[size] = 0; // make sure string is NUL terminated
13338 a->attachment_buffer[n] = buf;
13339 a->attachment_size[n] = size;
13341 printf("decode_post: attachment[%d] size %d data --->[%s]<---\n", n, (int)a->attachment_size[n], a->attachment_buffer[n]);
13342 }
13343
13344 string = strstr(p, boundary) + strlen(boundary);
13345 } else {
13346 const char* p = pitem;
13347 if (strstr(p, "\r\n\r\n"))
13348 p = strstr(p, "\r\n\r\n") + 4;
13349 else if (strstr(p, "\r\r\n\r\r\n"))
13350 p = strstr(p, "\r\r\n\r\r\n") + 6;
13351
13352 char* ppitem = (char*)strchr(pitem, '\"'); // NB: defeat "const char* string"
13353 if (ppitem)
13354 *ppitem = 0;
13355
13356 char* pb = (char*)(strstr(p, boundary)); // NB: defeat "const char* string"
13357 if (pb) {
13358 string = pb + strlen(boundary);
13359 *pb = 0;
13360 char* ptmp = (char*)(p + (strlen(p) - 1)); // NB: defeat "const char* string"
13361 while (*ptmp == '-' || *ptmp == '\n' || *ptmp == '\r')
13362 *ptmp-- = 0;
13363 } else {
13364 show_error(rr, "Invalid POST request");
13365 return;
13366 }
13368 printf("decode_post: [%s] = [%s]\n", pitem, p);
13369 param->setparam(pitem, p); // in decode_post()
13370 }
13371
13372 while (*string == '-' || *string == '\n' || *string == '\r')
13373 string++;
13374 }
13375
13376 } while ((POINTER_T) string - (POINTER_T) pinit < length);
13377
13378 char dec_path[256];
13379 mstrlcpy(dec_path, path, sizeof(dec_path));
13380
13381 interprete(param, rr, a, c, dec_path, t);
13382
13383 delete a;
13384 delete param;
13385}
char * attachment_buffer[3]
Definition mhttpd.cxx:67
size_t attachment_size[3]
Definition mhttpd.cxx:68
void initparam()
Definition mhttpd.cxx:717
DWORD n[4]
Definition mana.cxx:247
void show_error(Return *r, const char *error)
Definition mhttpd.cxx:1839
#define POINTER_T
Definition midas.h:166
char file_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decode_query()

void decode_query ( Param pp,
const char query_string 
)

Definition at line 13171 of file mhttpd.cxx.

13172{
13173 int len = strlen(query_string);
13174 char *buf = (char *)malloc(len+1);
13175 memcpy(buf, query_string, len+1);
13176 char* p = buf;
13177 p = strtok(p, "&");
13178 while (p != NULL) {
13179 char *pitem = p;
13180 p = strchr(p, '=');
13181 if (p != NULL) {
13182 *p++ = 0;
13183 urlDecode(pitem); // parameter name
13184 if (!equal_ustring(pitem, "format"))
13185 urlDecode(p); // parameter value
13186
13187 pp->setparam(pitem, p); // decoded query parameters
13188
13189 p = strtok(NULL, "&");
13190 }
13191 }
13192 free(buf);
13193}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3201
static void urlDecode(char *p)
Definition mhttpd.cxx:880
Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteHistPlotDeleted()

static void DeleteHistPlotDeleted ( HistPlot hp)
static

Definition at line 10481 of file mhttpd.cxx.

10482{
10483 /* delete variables according to "hist_order" */
10484
10485 while (1) {
10486 bool something_deleted = false;
10487 for (unsigned i=0; i<hp.vars.size(); i++) {
10488 if (hp.vars[i].order <= 0) {
10489 hp.vars.erase(hp.vars.begin() + i);
10490 something_deleted = true;
10491 }
10492 }
10493 if (!something_deleted)
10494 break;
10495 }
10496}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_jrpc()

void do_jrpc ( Param p,
Return r 
)

Definition at line 4318 of file mhttpd.cxx.

4319{
4320 int status;
4321
4322 const char *name = p->getparam("name");
4323 const char *cmd = p->getparam("rcmd");
4324 const char *args = p->getparam("rarg");
4325
4326 if (!name || !cmd || !args) {
4328 r->rsprintf("<INVALID_ARGUMENTS>");
4329 return;
4330 }
4331
4333
4334 int buf_length = 1024;
4335
4336 int max_reply_length = atoi(p->getparam("max_reply_length"));
4339
4340 char* buf = (char*)malloc(buf_length);
4341 buf[0] = 0;
4342
4343 HNDLE hconn;
4344
4346
4347 if (status != RPC_SUCCESS) {
4348 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4349 return;
4350 }
4351
4353
4354 if (status != RPC_SUCCESS) {
4355 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4356 return;
4357 }
4358
4359 r->rsprintf("%s", buf);
4360
4361 //status = cm_disconnect_client(hconn, FALSE);
4362
4363 free(buf);
4364}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2766
#define RPC_SUCCESS
Definition midas.h:698
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13472
#define RPC_JRPC
Definition mrpc.h:130
void show_text_header(Return *r)
Definition mhttpd.cxx:1827
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_jrpc_rev0()

void do_jrpc_rev0 ( Param p,
Return r 
)

Definition at line 4014 of file mhttpd.cxx.

4015{
4016 static RPC_LIST rpc_list[] = {
4017 { 9999, "mhttpd_jrpc_rev0", {
4018 {TID_STRING, RPC_IN}, // arg0
4019 {TID_STRING, RPC_IN}, // arg1
4020 {TID_STRING, RPC_IN}, // arg2
4021 {TID_STRING, RPC_IN}, // arg3
4022 {TID_STRING, RPC_IN}, // arg4
4023 {TID_STRING, RPC_IN}, // arg5
4024 {TID_STRING, RPC_IN}, // arg6
4025 {TID_STRING, RPC_IN}, // arg7
4026 {TID_STRING, RPC_IN}, // arg8
4027 {TID_STRING, RPC_IN}, // arg9
4028 {0}} },
4029 { 0 }
4030 };
4031
4032 int count = 0, substring = 0, rpc;
4033
4034 const char *xname = p->getparam("name");
4035 const char *srpc = p->getparam("rpc");
4036
4037 if (!srpc || !xname) {
4039 r->rsprintf("<INVALID_ARGUMENTS>");
4040 return;
4041 }
4042
4043 char sname[256];
4044 mstrlcpy(sname, xname, sizeof(sname));
4045
4046 if (sname[strlen(sname)-1]=='*') {
4047 sname[strlen(sname)-1] = 0;
4048 substring = 1;
4049 }
4050
4051 rpc = atoi(srpc);
4052
4055 r->rsprintf("<INVALID_RPC_ID>");
4056 return;
4057 }
4058
4059 rpc_list[0].id = rpc;
4061
4063 r->rsprintf("calling rpc %d | ", rpc);
4064
4065 if (1) {
4066 int status, i;
4067 char str[256];
4069
4071
4072 /* find client which exports FCNA function */
4073 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4074 if (status == DB_SUCCESS) {
4075 for (i=0; ; i++) {
4078 break;
4079
4080 sprintf(str, "RPC/%d", rpc);
4082 if (status == DB_SUCCESS) {
4083 char client_name[NAME_LENGTH];
4084 HNDLE hconn;
4085 int size;
4086
4087 size = sizeof(client_name);
4088 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4089 if (status != DB_SUCCESS)
4090 continue;
4091
4092 if (strlen(sname) > 0) {
4093 if (substring) {
4094 if (strstr(client_name, sname) != client_name)
4095 continue;
4096 } else {
4097 if (strcmp(sname, client_name) != 0)
4098 continue;
4099 }
4100 }
4101
4102 count++;
4103
4104 r->rsprintf("client %s", client_name);
4105
4106 status = cm_connect_client(client_name, &hconn);
4107 r->rsprintf(" %d", status);
4108
4109 if (status == RPC_SUCCESS) {
4111 p->getparam("arg0"),
4112 p->getparam("arg1"),
4113 p->getparam("arg2"),
4114 p->getparam("arg3"),
4115 p->getparam("arg4"),
4116 p->getparam("arg5"),
4117 p->getparam("arg6"),
4118 p->getparam("arg7"),
4119 p->getparam("arg8"),
4120 p->getparam("arg9")
4121 );
4122 r->rsprintf(" %d", status);
4123
4124 //status = cm_disconnect_client(hconn, FALSE);
4125 r->rsprintf(" %d", status);
4126 }
4127
4128 r->rsprintf(" | ");
4129 }
4130 }
4131 }
4132 }
4133
4134 r->rsprintf("rpc %d, called %d clients\n", rpc, count);
4135}
#define DB_NO_MORE_SUBKEYS
Definition midas.h:646
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5415
INT rpc_register_functions(const RPC_LIST *new_list, RPC_HANDLER func)
Definition midas.cxx:11827
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11573
double count
Definition mdump.cxx:33
#define RPC_IN
Definition midas.h:1580
#define RPC_MAX_ID
Definition midas.h:1607
#define NAME_LENGTH
Definition midas.h:272
Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_jrpc_rev1()

void do_jrpc_rev1 ( Param p,
Return r 
)

Definition at line 4139 of file mhttpd.cxx.

4140{
4141 static RPC_LIST rpc_list[] = {
4142 { 9998, "mhttpd_jrpc_rev1", {
4143 {TID_STRING, RPC_OUT}, // return string
4144 {TID_INT, RPC_IN}, // return string max length
4145 {TID_STRING, RPC_IN}, // arg0
4146 {TID_STRING, RPC_IN}, // arg1
4147 {TID_STRING, RPC_IN}, // arg2
4148 {TID_STRING, RPC_IN}, // arg3
4149 {TID_STRING, RPC_IN}, // arg4
4150 {TID_STRING, RPC_IN}, // arg5
4151 {TID_STRING, RPC_IN}, // arg6
4152 {TID_STRING, RPC_IN}, // arg7
4153 {TID_STRING, RPC_IN}, // arg8
4154 {TID_STRING, RPC_IN}, // arg9
4155 {0}} },
4156 { 0 }
4157 };
4158
4159 int status, substring = 0, rpc;
4160
4161 const char *xname = p->getparam("name");
4162 const char *srpc = p->getparam("rpc");
4163
4164 if (!srpc || !xname) {
4166 r->rsprintf("<INVALID_ARGUMENTS>");
4167 return;
4168 }
4169
4170 char sname[256];
4171 mstrlcpy(sname, xname, sizeof(sname));
4172
4173 if (sname[strlen(sname)-1]=='*') {
4174 sname[strlen(sname)-1] = 0;
4175 substring = 1;
4176 }
4177
4178 rpc = atoi(srpc);
4179
4182 r->rsprintf("<INVALID_RPC_ID>");
4183 return;
4184 }
4185
4186 rpc_list[0].id = rpc;
4188
4189 //printf("cm_register_functions() for format \'%s\' status %d\n", sformat, status);
4190
4192
4193 std::string reply_header;
4194 std::string reply_body;
4195
4196 //r->rsprintf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", HTTP_ENCODING);
4197 //r->rsprintf("<!-- created by MHTTPD on (timestamp) -->\n");
4198 //r->rsprintf("<jrpc_rev1>\n");
4199 //r->rsprintf(" <rpc>%d</rpc>\n", rpc);
4200
4201 if (1) {
4203
4205
4206 int buf_length = 1024;
4207
4208 int max_reply_length = atoi(p->getparam("max_reply_length"));
4211
4212 char* buf = (char*)malloc(buf_length);
4213
4214 /* find client which exports our RPC function */
4215 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4216 if (status == DB_SUCCESS) {
4217 for (int i=0; ; i++) {
4220 break;
4221
4222 char str[256];
4223 sprintf(str, "RPC/%d", rpc);
4225 if (status == DB_SUCCESS) {
4226 char client_name[NAME_LENGTH];
4227 HNDLE hconn;
4228 int size;
4229
4230 size = sizeof(client_name);
4231 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4232 if (status != DB_SUCCESS)
4233 continue;
4234
4235 if (strlen(sname) > 0) {
4236 if (substring) {
4237 if (strstr(client_name, sname) != client_name)
4238 continue;
4239 } else {
4240 if (strcmp(sname, client_name) != 0)
4241 continue;
4242 }
4243 }
4244
4245 //r->rsprintf(" <client>\n");
4246 //r->rsprintf(" <name>%s</name>\n", client_name);
4247
4248 int connect_status = -1;
4249 int call_status = -1;
4250 int call_length = 0;
4251 int disconnect_status = -1;
4252
4253 connect_status = cm_connect_client(client_name, &hconn);
4254
4255 //r->rsprintf(" <connect_status>%d</connect_status>\n", status);
4256
4257 if (connect_status == RPC_SUCCESS) {
4258 buf[0] = 0;
4259
4261 buf,
4262 buf_length,
4263 p->getparam("arg0"),
4264 p->getparam("arg1"),
4265 p->getparam("arg2"),
4266 p->getparam("arg3"),
4267 p->getparam("arg4"),
4268 p->getparam("arg5"),
4269 p->getparam("arg6"),
4270 p->getparam("arg7"),
4271 p->getparam("arg8"),
4272 p->getparam("arg9")
4273 );
4274
4275 //r->rsprintf(" <rpc_status>%d</rpc_status>\n", status);
4277 //r->rsputs("<data>");
4278 //r->rsputs(buf);
4279 //r->rsputs("</data>\n");
4280
4281 if (call_status == RPC_SUCCESS) {
4282 call_length = strlen(buf);
4283 reply_body += buf;
4284 }
4285
4286 //disconnect_status = cm_disconnect_client(hconn, FALSE);
4287 //r->rsprintf(" <disconnect_status>%d</disconnect_status>\n", status);
4288 }
4289
4290 //r->rsprintf(" </client>\n");
4291
4292 if (reply_header.length() > 0)
4293 reply_header += " | ";
4294
4295 char tmp[256];
4296 sprintf(tmp, "%s %d %d %d %d", client_name, connect_status, call_status, disconnect_status, call_length);
4297 reply_header += tmp;
4298 }
4299 }
4300 }
4301
4302 free(buf);
4303 }
4304
4305 //r->rsprintf(" <called_clients>%d</called_clients>\n", count);
4306 //r->rsprintf("</jrpc_rev1>\n");
4307
4308 if (reply_header.length() > 0) {
4309 r->rsputs(reply_header.c_str());
4310 r->rsputs(" || ");
4311 r->rsputs(reply_body.c_str());
4312 r->rsputs("\n");
4313 }
4314}
void rsputs(const char *str)
Definition mhttpd.cxx:600
#define TID_INT
Definition midas.h:338
#define RPC_OUT
Definition midas.h:1581
Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_src()

int evaluate_src ( char key,
char src,
double fvalue 
)

Definition at line 3497 of file mhttpd.cxx.

3498{
3499 HNDLE hDB, hkeyval;
3500 KEY vkey;
3501 int i, n, size, ivalue;
3502 char str[256], data[256];
3503
3505
3506 /* separate source from operators */
3507 for (i=0 ; i<(int)strlen(src) ; i++)
3508 if (src[i] == '>' || src[i] == '&')
3509 break;
3510 strncpy(str, src, i);
3511 str[i] = 0;
3512
3513 /* strip trailing blanks */
3514 while (strlen(str) > 0 && str[strlen(str)-1] == ' ')
3515 str[strlen(str)-1] = 0;
3516
3517 db_find_key(hDB, 0, str, &hkeyval);
3518 if (!hkeyval) {
3519 cm_msg(MERROR, "evaluate_src", "Invalid Src key \"%s\" for Fill \"%s\"",
3520 src, key);
3521 return 0;
3522 }
3523
3525 size = sizeof(data);
3526 db_get_value(hDB, 0, src, data, &size, vkey.type, FALSE);
3527 std::string value = db_sprintf(data, size, 0, vkey.type);
3528 if (equal_ustring(value.c_str(), "NAN"))
3529 return 0;
3530
3531 if (vkey.type == TID_BOOL) {
3532 *fvalue = (value[0] == 'y');
3533 } else
3534 *fvalue = atof(value.c_str());
3535
3536 /* evaluate possible operators */
3537 do {
3538 if (src[i] == '>' && src[i+1] == '>') {
3539 i+=2;
3540 n = atoi(src+i);
3541 while (src[i] == ' ' || isdigit(src[i]))
3542 i++;
3543 ivalue = (int)*fvalue;
3544 ivalue >>= n;
3545 *fvalue = ivalue;
3546 }
3547
3548 if (src[i] == '&') {
3549 i+=1;
3550 while (src[i] == ' ')
3551 i++;
3552 if (src[i] == '0' && src[i+1] == 'x')
3553 sscanf(src+2+i, "%x", &n);
3554 else
3555 n = atoi(src+i);
3556 while (src[i] == ' ' || isxdigit(src[i]) || src[i] == 'x')
3557 i++;
3558 ivalue = (int)*fvalue;
3559 ivalue &= n;
3560 *fvalue = ivalue;
3561 }
3562
3563 } while (src[i]);
3564
3565 return 1;
3566}
#define TID_BOOL
Definition midas.h:340
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10843
void * data
Definition mana.cxx:268
Here is the call graph for this function:
Here is the caller graph for this function:

◆ export_hist()

void export_hist ( MVOdb odb,
Return r,
const char group,
const char panel,
time_t  endtime,
int  scale,
int  index,
int  labels 
)

Definition at line 11025 of file mhttpd.cxx.

11026{
11027 //HNDLE hDB, hkey, hkeypanel;
11028 //int size;
11029 int status;
11030 //char str[256];
11031
11032 int debug = 0;
11033
11034 ss_tzset(); // required for localtime_r()
11035
11036#if 0
11038
11039 /* check panel name in ODB */
11040 sprintf(str, "/History/Display/%s/%s", group, panel);
11042 if (!hkeypanel) {
11043 sprintf(str, "Cannot find /History/Display/%s/%s in ODB\n", group, panel);
11044 show_error(r, str);
11045 return;
11046 }
11047
11048 /* get runmarker flag */
11049 BOOL runmarker = 1;
11050 size = sizeof(runmarker);
11051 db_get_value(hDB, hkeypanel, "Show run markers", &runmarker, &size, TID_BOOL, TRUE);
11052
11053 if (scale == 0) {
11054 /* get timescale */
11055 std::string ts = "1h";
11056 status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
11057 if (status != DB_SUCCESS) {
11058 /* delete old integer key */
11059 db_find_key(hDB, hkeypanel, "Timescale", &hkey);
11060 if (hkey)
11062
11063 ts = "1h";
11064 status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
11065 }
11066
11067 scale = time_to_sec(ts.c_str());
11068 }
11069#endif
11070
11071 time_t now = ss_time();
11072
11073 if (endtime == 0)
11074 endtime = now;
11075
11078
11079 HistPlot hp;
11081
11082 time_t starttime = endtime - scale;
11083
11084 //printf("start %.0f, end %.0f, scale %.0f\n", (double)starttime, (double)endtime, (double)scale);
11085
11086 status = read_history(hp, /*hDB, group, panel,*/ index, hp.show_run_markers, starttime, endtime, 0, hsdata);
11087 if (status != HS_SUCCESS) {
11088 char str[256];
11089 sprintf(str, "History error, status %d\n", status);
11090 show_error(r, str);
11091 return;
11092 }
11093
11094 if (debug)
11095 hsdata->Print();
11096
11097 int *i_var = (int *)malloc(sizeof(int)*hsdata->nvars);
11098
11099 for (int i = 0; i < hsdata->nvars; i++)
11100 i_var[i] = -1;
11101
11102 time_t t = 0;
11103
11104 /* find first time where all variables are available */
11105 for (int i = 0; i < hsdata->nvars; i++)
11106 if (hsdata->odb_index[i] >= 0)
11107 if (hsdata->num_entries[i] > 0)
11108 if ((t == 0) || (hsdata->t[i][0] > t))
11109 t = hsdata->t[i][0];
11110
11111 if (t == 0 && hsdata->nvars > 1) {
11112 show_error(r, "No history available for choosen period");
11113 free(i_var);
11114 return;
11115 }
11116
11117 int run_index = -1;
11118 int state_index = -1;
11119 int n_run_number = 0;
11121 if (hp.show_run_markers)
11122 for (int i = 0; i < hsdata->nvars; i++) {
11123 if (hsdata->odb_index[i] == -2) {
11124 n_run_number = hsdata->num_entries[i];
11125 t_run_number = hsdata->t[i];
11126 run_index = i;
11127 } else if (hsdata->odb_index[i] == -1) {
11128 state_index = i;
11129 }
11130 }
11131
11132 //printf("runmarker %d, state %d, run %d\n", runmarker, state_index, run_index);
11133
11134 /* header */
11135 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
11136 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
11137 r->rsprintf("Accept-Ranges: bytes\r\n");
11138 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
11139 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
11140 r->rsprintf("Content-Type: text/plain\r\n");
11141 r->rsprintf("Content-disposition: attachment; filename=\"export.csv\"\r\n");
11142 r->rsprintf("\r\n");
11143
11144 /* output header line with variable names */
11145 if (hp.show_run_markers && t_run_number)
11146 r->rsprintf("Time, Timestamp, Run, Run State, ");
11147 else
11148 r->rsprintf("Time, Timestamp, ");
11149
11150 for (int i = 0, first = 1; i < hsdata->nvars; i++) {
11151 if (hsdata->odb_index[i] < 0)
11152 continue;
11153 if (hsdata->num_entries[i] <= 0)
11154 continue;
11155 if (!first)
11156 r->rsprintf(", ");
11157 first = 0;
11158 r->rsprintf("%s", hsdata->var_names[i]);
11159 }
11160 r->rsprintf("\n");
11161
11162 int i_run = 0;
11163
11164 do {
11165
11166 if (debug)
11167 printf("hsdata %p, t %d, irun %d\n", hsdata, (int)t, i_run);
11168
11169 /* find run number/state which is valid for t */
11170 if (hp.show_run_markers && t_run_number)
11171 while (i_run < n_run_number-1 && t_run_number[i_run+1] <= t)
11172 i_run++;
11173
11174 //printf("irun %d\n", i_run);
11175
11176 /* find index for all variables which is valid for t */
11177 for (int i = 0; i < hsdata->nvars; i++)
11178 while (hsdata->num_entries[i] > 0 && i_var[i] < hsdata->num_entries[i] - 1 && hsdata->t[i][i_var[i]+1] <= t)
11179 i_var[i]++;
11180
11181 /* finish if last point for all variables reached */
11182 bool done = true;
11183 for (int i = 0 ; i < hsdata->nvars ; i++)
11184 if (hsdata->num_entries[i] > 0 && i_var[i] < hsdata->num_entries[i]) {
11185 done = false;
11186 break;
11187 }
11188
11189 if (debug) {
11190 printf("step to time %d: ", (int)t);
11191 for (int i = 0; i < hsdata->nvars; i++) {
11192 printf(" [%d] %d, ", hsdata->num_entries[i], i_var[i]);
11193 }
11194 printf(" done: %d\n", done);
11195 }
11196
11197 if (done)
11198 break;
11199
11200 struct tm tms;
11201 localtime_r(&t, &tms);
11202
11203 char fmt[256];
11204 //strcpy(fmt, "%c");
11205 strcpy(fmt, "%Y.%m.%d %H:%M:%S");
11206 char str[256];
11207 strftime(str, sizeof(str), fmt, &tms);
11208
11209 if (t_run_number && run_index>=0 && state_index>=0) {
11210 if (t_run_number[i_run] <= t)
11211 r->rsprintf("%s, %d, %.0f, %.0f, ", str, (int)t, hsdata->v[run_index][i_run], hsdata->v[state_index][i_run]);
11212 else
11213 r->rsprintf("%s, %d, N/A, N/A, ", str, (int)t);
11214 } else
11215 r->rsprintf("%s, %d, ", str, (int)t);
11216
11217 if (debug) {
11218 for (int i= 0 ; i < hsdata->nvars ; i++)
11219 printf(" %d (%g)", i_var[i], hsdata->v[i][i_var[i]]);
11220 printf("\n");
11221 }
11222
11223 for (int i=0, first=1 ; i<hsdata->nvars ; i++) {
11224 if (i_var[i] < 0)
11225 continue;
11226 if (hsdata->odb_index[i] < 0)
11227 continue;
11228 if (!first)
11229 r->rsprintf(", ");
11230 first = 0;
11231 //r->rsprintf("(%d %g)", i_var[i], hsdata->v[i][i_var[i]]);
11232 r->rsprintf("%g", hsdata->v[i][i_var[i]]);
11233 }
11234 r->rsprintf("\n");
11235
11236 /* find next t as smallest delta t */
11237 int dt = -1;
11238 for (int i = 0 ; i < hsdata->nvars ; i++)
11239 if (i_var[i]>=0 && hsdata->odb_index[i]>=0 && hsdata->num_entries[i]>0 && i_var[i]<hsdata->num_entries[i]-1) {
11240 int xdt = hsdata->t[i][i_var[i]+1] - t;
11241 if (debug)
11242 printf("var %d, i_var %d->%d, t %d->%d, dt %d\n", i, i_var[i], i_var[i]+1, (int)hsdata->t[i][i_var[i]], (int)hsdata->t[i][i_var[i]+1], xdt);
11243 if (dt <= 0 || xdt < dt)
11244 dt = xdt;
11245 }
11246
11247 if (debug)
11248 printf("dt %d\n", dt);
11249
11250 if (dt <= 0)
11251 break;
11252
11253 t += dt;
11254
11255 } while (1);
11256
11257 free(i_var);
11258}
int done
TRIGGER_SETTINGS ts
#define HS_SUCCESS
Definition midas.h:727
void ss_tzset()
Definition system.cxx:3355
DWORD ss_time()
Definition system.cxx:3462
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3856
INT index
Definition mana.cxx:271
int read_history(const HistPlot &hp, int index, int flags, time_t tstart, time_t tend, time_t scale, HistoryData *data)
Definition mhttpd.cxx:8356
int time_to_sec(const char *str)
Definition mhttpd.cxx:8092
static void LoadHistPlotFromOdb(MVOdb *odb, HistPlot *hp, const char *group, const char *panel)
Definition mhttpd.cxx:10195
DWORD BOOL
Definition midas.h:105
MUTEX_T * tm
Definition odbedit.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_cookie_mg()

static const std::string find_cookie_mg ( const struct http_message msg,
const char cookie_name 
)
static

Definition at line 14154 of file mhttpd.cxx.

14155{
14156 const std::string cookies = find_header_mg(msg, "Cookie");
14157 if (cookies.length() < 1)
14158 return "";
14159 const char* p = strstr(cookies.c_str(), cookie_name);
14160 if (!p)
14161 return "";
14162 const char* v = p+strlen(cookie_name);
14163 if (*v != '=')
14164 return "";
14165 v++;
14166 //printf("cookie [%s] value [%s]\n", cookie_name, v);
14167 return v;
14168}
static const std::string find_header_mg(const struct http_message *msg, const char *name)
Definition mhttpd.cxx:14141
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_file_mg()

int find_file_mg ( const char filename,
std::string &  path,
FILE **  fpp,
bool  trace 
)

Definition at line 13672 of file mhttpd.cxx.

13673{
13674 std::string exptdir = cm_get_path();
13675
13676 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13677 return SUCCESS;
13678
13679 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13680 return SUCCESS;
13681
13682 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13683 return SUCCESS;
13684
13685 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13686 return SUCCESS;
13687
13688 // setup default filename
13689 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13690 return SS_FILE_ERROR;
13691}
std::string cm_get_path()
Definition midas.cxx:1537
#define SS_FILE_ERROR
Definition midas.h:669
#define SUCCESS
Definition mcstd.h:54
int try_file_mg(const char *try_dir, const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13639
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_header_mg()

static const std::string find_header_mg ( const struct http_message msg,
const char name 
)
static

Definition at line 14141 of file mhttpd.cxx.

14142{
14143 size_t nlen = strlen(name);
14144 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14145 if (msg->header_names[i].len != nlen)
14146 continue;
14147 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14148 continue;
14149 return mgstr(&msg->header_values[i]);
14150 }
14151 return "";
14152}
struct mg_str header_names[MG_MAX_HTTP_HEADERS]
Definition mongoose6.h:2090
#define MG_MAX_HTTP_HEADERS
Definition mongoose6.h:2031
struct mg_str header_values[MG_MAX_HTTP_HEADERS]
Definition mongoose6.h:2091
size_t len
Definition mongoose6.h:1207
const char * p
Definition mongoose6.h:1206
static std::string mgstr(const mg_str *s)
Definition mhttpd.cxx:14136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_odb_tag()

char * find_odb_tag ( char p,
char path,
char format,
int edit,
char type,
char pwd,
char tail 
)

Definition at line 3091 of file mhttpd.cxx.

3092{
3093 char str[256], *ps, *pt;
3095
3096 *edit = 0;
3097 *tail = 0;
3098 *format = 0;
3099 pwd[0] = 0;
3100 in_script = FALSE;
3101 strcpy(type, "text");
3102 do {
3103 while (*p && *p != '<')
3104 p++;
3105
3106 /* return if end of string reached */
3107 if (!*p)
3108 return NULL;
3109
3110 p++;
3111 while (*p && ((*p == ' ') || iscntrl(*p)))
3112 p++;
3113
3114 strncpy(str, p, 6);
3115 str[6] = 0;
3116 if (equal_ustring(str, "script"))
3117 in_script = TRUE;
3118
3119 strncpy(str, p, 7);
3120 str[7] = 0;
3121 if (equal_ustring(str, "/script"))
3122 in_script = FALSE;
3123
3124 strncpy(str, p, 4);
3125 str[4] = 0;
3126 if (equal_ustring(str, "odb ")) {
3127 ps = p - 1;
3128 p += 4;
3129 while (*p && ((*p == ' ') || iscntrl(*p)))
3130 p++;
3131
3132 do {
3133 strncpy(str, p, 7);
3134 str[7] = 0;
3135 if (equal_ustring(str, "format=")) {
3136 p += 7;
3137 if (*p == '\"') {
3138 p++;
3139 while (*p && *p != '\"')
3140 *format++ = *p++;
3141 *format = 0;
3142 if (*p == '\"')
3143 p++;
3144 } else {
3145 while (*p && *p != ' ' && *p != '>')
3146 *format++ = *p++;
3147 *format = 0;
3148 }
3149
3150 } else {
3151
3152 strncpy(str, p, 4);
3153 str[4] = 0;
3154 if (equal_ustring(str, "src=")) {
3155 p += 4;
3156 if (*p == '\"') {
3157 p++;
3158 while (*p && *p != '\"')
3159 *path++ = *p++;
3160 *path = 0;
3161 if (*p == '\"')
3162 p++;
3163 } else {
3164 while (*p && *p != ' ' && *p != '>')
3165 *path++ = *p++;
3166 *path = 0;
3167 }
3168 } else {
3169
3170 if (in_script)
3171 break;
3172
3173 strncpy(str, p, 5);
3174 str[5] = 0;
3175 if (equal_ustring(str, "edit=")) {
3176 p += 5;
3177
3178 if (*p == '\"') {
3179 p++;
3180 *edit = atoi(p);
3181 if (*p == '\"')
3182 p++;
3183 } else {
3184 *edit = atoi(p);
3185 while (*p && *p != ' ' && *p != '>')
3186 p++;
3187 }
3188
3189 } else {
3190
3191 strncpy(str, p, 5);
3192 str[5] = 0;
3193 if (equal_ustring(str, "type=")) {
3194 p += 5;
3195 if (*p == '\"') {
3196 p++;
3197 while (*p && *p != '\"')
3198 *type++ = *p++;
3199 *type = 0;
3200 if (*p == '\"')
3201 p++;
3202 } else {
3203 while (*p && *p != ' ' && *p != '>')
3204 *type++ = *p++;
3205 *type = 0;
3206 }
3207 } else {
3208 strncpy(str, p, 4);
3209 str[4] = 0;
3210 if (equal_ustring(str, "pwd=")) {
3211 p += 4;
3212 if (*p == '\"') {
3213 p++;
3214 while (*p && *p != '\"')
3215 *pwd++ = *p++;
3216 *pwd = 0;
3217 if (*p == '\"')
3218 p++;
3219 } else {
3220 while (*p && *p != ' ' && *p != '>')
3221 *pwd++ = *p++;
3222 *pwd = 0;
3223 }
3224 } else {
3225 if (strchr(p, '=')) {
3226 mstrlcpy(str, p, sizeof(str));
3227 pt = strchr(str, '=')+1;
3228 if (*pt == '\"') {
3229 pt++;
3230 while (*pt && *pt != '\"')
3231 pt++;
3232 if (*pt == '\"')
3233 pt++;
3234 *pt = 0;
3235 } else {
3236 while (*pt && *pt != ' ' && *pt != '>')
3237 pt++;
3238 *pt = 0;
3239 }
3240 if (tail[0]) {
3241 mstrlcat(tail, " ", 256);
3242 mstrlcat(tail, str, 256);
3243 } else {
3244 mstrlcat(tail, str, 256);
3245 }
3246 p += strlen(str);
3247 }
3248 }
3249 }
3250 }
3251 }
3252 }
3253
3254 while (*p && ((*p == ' ') || iscntrl(*p)))
3255 p++;
3256
3257 if (*p == '<') {
3258 cm_msg(MERROR, "find_odb_tag", "Invalid odb tag '%s'", ps);
3259 return NULL;
3260 }
3261 } while (*p != '>');
3262
3263 return ps;
3264 }
3265
3266 while (*p && *p != '>')
3267 p++;
3268
3269 } while (1);
3270
3271}
INT type
Definition mana.cxx:269
char pwd[256]
Definition odbedit.cxx:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gen_odb_attachment()

void gen_odb_attachment ( Return r,
const char path,
std::string &  bout 
)

Definition at line 2134 of file mhttpd.cxx.

2135{
2137 KEY key;
2138 INT i, j, size;
2139 char data[1024];
2140 time_t now;
2141
2143 db_find_key(hDB, 0, path, &hkeyroot);
2144 assert(hkeyroot);
2145
2146 /* title row */
2147 //size = sizeof(str);
2148 //str[0] = 0;
2149 //db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
2150 time(&now);
2151
2152 bout += "<table border=3 cellpadding=1 class=\"dialogTable\">\n";
2153 char ctimebuf[32];
2154 ctime_r(&now, ctimebuf);
2155 bout += msprintf("<tr><th colspan=2>%s</tr>\n", ctimebuf);
2156 bout += msprintf("<tr><th colspan=2>%s</tr>\n", path);
2157
2158 /* enumerate subkeys */
2159 for (i = 0;; i++) {
2161 if (!hkey)
2162 break;
2163 db_get_key(hDB, hkey, &key);
2164
2165 /* resolve links */
2166 if (key.type == TID_LINK) {
2168 db_get_key(hDB, hkey, &key);
2169 }
2170
2171 if (key.type == TID_KEY) {
2172 /* for keys, don't display data value */
2173 bout += msprintf("<tr><td colspan=2>%s</td></tr>\n", key.name);
2174 } else {
2175 /* display single value */
2176 if (key.num_values == 1) {
2177 size = sizeof(data);
2178 db_get_data(hDB, hkey, data, &size, key.type);
2179 //printf("data size %d [%s]\n", size, data);
2180 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2181 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2182
2183 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2184 data_str = "(empty)";
2185 hex_str = "";
2186 }
2187
2188 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2189 //sprintf(b, "<tr><td>%s</td><td>%s (%s)</td></tr>\n", key.name, data_str, hex_str);
2190 bout += "<tr><td>";
2191 bout += key.name;
2192 bout += "</td><td>";
2193 bout += data_str;
2194 bout += " (";
2195 bout += hex_str;
2196 bout += ")</td></tr>\n";
2197 } else {
2198 bout += msprintf("<tr><td>%s</td><td>", key.name);
2199 bout += strencode2(data_str.c_str());
2200 bout += "</td></tr>\n";
2201 }
2202 } else {
2203 /* display first value */
2204 bout += msprintf("<tr><td rowspan=%d>%s</td>\n", key.num_values, key.name);
2205
2206 for (j = 0; j < key.num_values; j++) {
2207 size = sizeof(data);
2208 db_get_data_index(hDB, hkey, data, &size, j, key.type);
2209 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2210 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2211
2212 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2213 data_str = "(empty)";
2214 hex_str = "";
2215 }
2216
2217 if (j > 0) {
2218 bout += "<tr>";
2219 }
2220
2221 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2222 //sprintf(b, "<td>[%d] %s (%s)<br></td></tr>\n", j, data_str, hex_str);
2223 bout += "<td>[";
2224 bout += toString(j);
2225 bout += "] ";
2226 bout += data_str;
2227 bout += " (";
2228 bout += hex_str;
2229 bout += ")<br></td></tr>\n";
2230 } else {
2231 //sprintf(b, "<td>[%d] %s<br></td></tr>\n", j, data_str);
2232 bout += "<td>[";
2233 bout += toString(j);
2234 bout += "] ";
2235 bout += data_str;
2236 bout += "<br></td></tr>\n";
2237 }
2238 }
2239 }
2240 }
2241 }
2242
2243 bout += "</table>\n";
2244}
#define TID_KEY
Definition midas.h:349
#define TID_LINK
Definition midas.h:350
INT db_sprintfh(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10983
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6893
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5725
std::string strencode2(const char *text)
Definition mhttpd.cxx:2047
static std::string toString(int i)
Definition mhttpd.cxx:55
std::string msprintf(const char *format,...)
Definition midas.cxx:410
INT j
Definition odbhist.cxx:40
INT num_values
Definition midas.h:1028
DWORD type
Definition midas.h:1027
INT item_size
Definition midas.h:1032
Here is the call graph for this function:
Here is the caller graph for this function:

◆ generate_hist_graph()

void generate_hist_graph ( MVOdb odb,
Return rr,
const char hgroup,
const char hpanel,
char buffer,
int buffer_size,
int  width,
int  height,
time_t  xendtime,
int  scale,
int  index,
int  labels,
const char bgcolor,
const char fgcolor,
const char gridcolor 
)
  • check panel name in ODB *‍/
  • split varname in event, variable and index *‍/
  • get factors *‍/
  • get offsets *‍/
  • get axis type *‍/
  • get show_values type *‍/
  • get sort_vars type *‍/
  • get old_vars type *‍/
  • get min value *‍/
  • get max value *‍/
  • get runmarker flag *‍/

Definition at line 8604 of file mhttpd.cxx.

8610{
8611 HNDLE hDB;
8612 //KEY key;
8613 gdImagePtr im;
8615 int i, j, k, l;
8616 //int n_vars;
8617 int size, status, r, g, b;
8618 //int x_marker;
8619 int length;
8620 int white, grey, red;
8621 //int black, ltgrey, green, blue;
8622 int fgcol, bgcol, gridcol;
8623 int curve_col[MAX_VARS];
8624 int state_col[3];
8625 char str[256], *p;
8626 //INT var_index[MAX_VARS];
8627 //char event_name[MAX_VARS][NAME_LENGTH];
8628 //char tag_name[MAX_VARS][64];
8629 //char var_name[MAX_VARS][NAME_LENGTH];
8630 //char varname[64];
8631 //char key_name[256];
8632 //float factor[MAX_VARS], offset[MAX_VARS];
8633 //BOOL logaxis, runmarker;
8634 //double xmin, xrange;
8635 double ymin, ymax;
8637 //float minvalue = (float) -HUGE_VAL;
8638 //float maxvalue = (float) +HUGE_VAL;
8639 //int show_values = 0;
8640 //int sort_vars = 0;
8641 //int old_vars = 0;
8643 int flags;
8644
8645 time_t now = ss_time();
8646
8647 if (xendtime == 0)
8648 xendtime = now;
8649
8650 HistPlot hp;
8652
8653 std::vector<int> var_index; var_index.resize(hp.vars.size());
8654
8655 for (size_t i=0; i<hp.vars.size(); i++) {
8656 var_index[i] = 0;
8657 const char *vp = strchr(hp.vars[i].tag_name.c_str(), '[');
8658 if (vp) {
8659 var_index[i] = atoi(vp + 1);
8660 }
8661 }
8662
8663 int logaxis = hp.log_axis;
8664 double minvalue = hp.minimum;
8665 double maxvalue = hp.maximum;
8666
8667 if ((minvalue == 0) && (maxvalue == 0)) {
8668 minvalue = -HUGE_VAL;
8669 maxvalue = +HUGE_VAL;
8670 }
8671
8672 std::vector<int> x[MAX_VARS];
8673 std::vector<double> y[MAX_VARS];
8674
8677
8679
8680 /* generate image */
8681 im = gdImageCreate(width, height);
8682
8683 /* allocate standard colors */
8684 sscanf(bgcolor, "%02x%02x%02x", &r, &g, &b);
8685 bgcol = gdImageColorAllocate(im, r, g, b);
8686 sscanf(fgcolor, "%02x%02x%02x", &r, &g, &b);
8687 fgcol = gdImageColorAllocate(im, r, g, b);
8688 sscanf(gridcolor, "%02x%02x%02x", &r, &g, &b);
8689 gridcol = gdImageColorAllocate(im, r, g, b);
8690
8691 grey = gdImageColorAllocate(im, 192, 192, 192);
8692 //ltgrey = gdImageColorAllocate(im, 208, 208, 208);
8693 white = gdImageColorAllocate(im, 255, 255, 255);
8694 //black = gdImageColorAllocate(im, 0, 0, 0);
8695 red = gdImageColorAllocate(im, 255, 0, 0);
8696 //green = gdImageColorAllocate(im, 0, 255, 0);
8697 //blue = gdImageColorAllocate(im, 0, 0, 255);
8698
8699 curve_col[0] = gdImageColorAllocate(im, 0, 0, 255);
8700 curve_col[1] = gdImageColorAllocate(im, 0, 192, 0);
8701 curve_col[2] = gdImageColorAllocate(im, 255, 0, 0);
8702 curve_col[3] = gdImageColorAllocate(im, 0, 192, 192);
8703 curve_col[4] = gdImageColorAllocate(im, 255, 0, 255);
8704 curve_col[5] = gdImageColorAllocate(im, 192, 192, 0);
8705 curve_col[6] = gdImageColorAllocate(im, 128, 128, 128);
8706 curve_col[7] = gdImageColorAllocate(im, 128, 255, 128);
8707 curve_col[8] = gdImageColorAllocate(im, 255, 128, 128);
8708 curve_col[9] = gdImageColorAllocate(im, 128, 128, 255);
8709 for (i=10; i<MAX_VARS; i++)
8710 curve_col[i] = gdImageColorAllocate(im, 128, 128, 128);
8711
8712 state_col[0] = gdImageColorAllocate(im, 255, 0, 0);
8713 state_col[1] = gdImageColorAllocate(im, 255, 255, 0);
8714 state_col[2] = gdImageColorAllocate(im, 0, 255, 0);
8715
8716 /* Set transparent color. */
8718
8719 /* Title */
8720 gdImageString(im, gdFontGiant, width / 2 - (strlen(hpanel) * gdFontGiant->w) / 2, 2, (char*)hpanel, fgcol);
8721
8722 /* connect to history */
8724 if (mh == NULL) {
8725 sprintf(str, "History is not configured, see messages");
8726 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8727 goto error;
8728 }
8729
8731 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
8732 //db_find_key(hDB, 0, str, &hkeypanel);
8733 //if (!hkeypanel) {
8734 // sprintf(str, "Cannot find /History/Display/%s/%s in ODB", hgroup, hpanel);
8735 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8736 // goto error;
8737 //}
8738
8739 //db_find_key(hDB, hkeypanel, "Variables", &hkeydvar);
8740 //if (!hkeydvar) {
8741 // sprintf(str, "Cannot find /History/Display/%s/%s/Variables in ODB", hgroup, hpanel);
8742 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8743 // goto error;
8744 //}
8745
8746 //db_get_key(hDB, hkeydvar, &key);
8747 //n_vars = key.num_values;
8748
8749 if (hp.vars.empty()) {
8750 sprintf(str, "No variables in panel %s/%s", hgroup, hpanel);
8751 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8752 goto error;
8753 }
8754
8755 if (hp.vars.size() > MAX_VARS) {
8756 sprintf(str, "Too many variables in panel %s/%s", hgroup, hpanel);
8757 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8758 goto error;
8759 }
8760
8761 ymin = ymax = 0;
8762 //logaxis = runmarker = 0;
8763
8764 for (i = 0; i < (int)hp.vars.size(); i++) {
8765 if (index != -1 && index != i)
8766 continue;
8767
8768 //size = sizeof(str);
8769 //status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
8770 //if (status != DB_SUCCESS) {
8771 // sprintf(str, "Cannot read tag %d in panel %s/%s, status %d", i, hgroup, hpanel, status);
8772 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8773 // goto error;
8774 //}
8775 //
8776 //mstrlcpy(tag_name[i], str, sizeof(tag_name[0]));
8777
8779 //char *tp = strchr(tag_name[i], ':');
8780 //if (tp) {
8781 // mstrlcpy(event_name[i], tag_name[i], sizeof(event_name[0]));
8782 // char *ep = strchr(event_name[i], ':');
8783 // if (ep)
8784 // *ep = 0;
8785 // mstrlcpy(var_name[i], tp+1, sizeof(var_name[0]));
8786 // var_index[i] = 0;
8787 // char *vp = strchr(var_name[i], '[');
8788 // if (vp) {
8789 // var_index[i] = atoi(vp + 1);
8790 // *vp = 0;
8791 // }
8792 //} else {
8793 // sprintf(str, "Tag \"%s\" has wrong format in panel \"%s/%s\"", tag_name[i], hgroup, hpanel);
8794 // gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
8795 // goto error;
8796 //}
8797 //
8798 //db_find_key(hDB, hkeypanel, "Colour", &hkey);
8799 //if (hkey) {
8800 // size = sizeof(str);
8801 // status = db_get_data_index(hDB, hkey, str, &size, i, TID_STRING);
8802 // if (status == DB_SUCCESS) {
8803 // if (str[0] == '#') {
8804 // char sss[3];
8805 // int r, g, b;
8806 //
8807 // sss[0] = str[1];
8808 // sss[1] = str[2];
8809 // sss[2] = 0;
8810 // r = strtoul(sss, NULL, 16);
8811 // sss[0] = str[3];
8812 // sss[1] = str[4];
8813 // sss[2] = 0;
8814 // g = strtoul(sss, NULL, 16);
8815 // sss[0] = str[5];
8816 // sss[1] = str[6];
8817 // sss[2] = 0;
8818 // b = strtoul(sss, NULL, 16);
8819 //
8820 // curve_col[i] = gdImageColorAllocate(im, r, g, b);
8821 // }
8822 // }
8823 //}
8824
8825 if (hp.vars[i].colour[0] == '#') {
8826 const char* str = hp.vars[i].colour.c_str();
8827 char sss[3];
8828 int r, g, b;
8829
8830 sss[0] = str[1];
8831 sss[1] = str[2];
8832 sss[2] = 0;
8833 r = strtoul(sss, NULL, 16);
8834 sss[0] = str[3];
8835 sss[1] = str[4];
8836 sss[2] = 0;
8837 g = strtoul(sss, NULL, 16);
8838 sss[0] = str[5];
8839 sss[1] = str[6];
8840 sss[2] = 0;
8841 b = strtoul(sss, NULL, 16);
8842
8843 curve_col[i] = gdImageColorAllocate(im, r, g, b);
8844 }
8845
8846 /* get timescale */
8847 if (scale == 0) {
8848 //std::string ts = "1h";
8849 //status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
8850 //if (status != DB_SUCCESS) {
8851 // /* delete old integer key */
8852 // db_find_key(hDB, hkeypanel, "Timescale", &hkey);
8853 // if (hkey)
8854 // db_delete_key(hDB, hkey, FALSE);
8855 //
8856 // ts = "1h";
8857 // status = db_get_value_string(hDB, hkeypanel, "Timescale", 0, &ts, TRUE);
8858 //}
8859
8860 scale = time_to_sec(hp.timescale.c_str());
8861 }
8862
8863 //for (j = 0; j < MAX_VARS; j++) {
8864 // factor[j] = 1;
8865 // offset[j] = 0;
8866 //}
8867
8869 //size = sizeof(float) * n_vars;
8870 //db_get_value(hDB, hkeypanel, "Factor", factor, &size, TID_FLOAT, TRUE);
8871
8873 //size = sizeof(float) * n_vars;
8874 //db_get_value(hDB, hkeypanel, "Offset", offset, &size, TID_FLOAT, TRUE);
8875
8877 //size = sizeof(logaxis);
8878 //logaxis = 0;
8879 //db_get_value(hDB, hkeypanel, "Log axis", &logaxis, &size, TID_BOOL, TRUE);
8880
8882 //size = sizeof(show_values);
8883 //show_values = 0;
8884 //db_get_value(hDB, hkeypanel, "Show values", &show_values, &size, TID_BOOL, TRUE);
8885
8887 //size = sizeof(sort_vars);
8888 //sort_vars = 0;
8889 //db_get_value(hDB, hkeypanel, "Sort vars", &sort_vars, &size, TID_BOOL, TRUE);
8890
8892 //size = sizeof(old_vars);
8893 //old_vars = 0;
8894 //db_get_value(hDB, hkeypanel, "Show old vars", &old_vars, &size, TID_BOOL, TRUE);
8895
8897 //size = sizeof(minvalue);
8898 //minvalue = (float) -HUGE_VAL;
8899 //db_get_value(hDB, hkeypanel, "Minimum", &minvalue, &size, TID_FLOAT, TRUE);
8900
8902 //size = sizeof(maxvalue);
8903 //maxvalue = (float) +HUGE_VAL;
8904 //db_get_value(hDB, hkeypanel, "Maximum", &maxvalue, &size, TID_FLOAT, TRUE);
8905
8906 //if ((minvalue == 0) && (maxvalue == 0)) {
8907 // minvalue = (float) -HUGE_VAL;
8908 // maxvalue = (float) +HUGE_VAL;
8909 //}
8910
8912 //size = sizeof(runmarker);
8913 //runmarker = 1;
8914 //db_get_value(hDB, hkeypanel, "Show run markers", &runmarker, &size, TID_BOOL, TRUE);
8915
8916 /* make ODB path from tag name */
8917 std::string odbpath;
8918 HNDLE hkeyeq = 0;
8920 db_find_key(hDB, 0, "/Equipment", &hkeyroot);
8921 if (hkeyroot) {
8922 for (j = 0;; j++) {
8923 HNDLE hkeyeq;
8925
8926 if (!hkeyeq)
8927 break;
8928
8929 KEY key;
8931 if (equal_ustring(key.name, hp.vars[i].event_name.c_str())) {
8932 /* check if variable is individual key under variables/ */
8933 sprintf(str, "Variables/%s", hp.vars[i].tag_name.c_str());
8934 HNDLE hkey;
8936 if (hkey) {
8937 //sprintf(odbpath, "/Equipment/%s/Variables/%s", event_name[i], var_name[i]);
8938 odbpath = "";
8939 odbpath += "/Equipment/";
8940 odbpath += hp.vars[i].event_name;
8941 odbpath += "/Variables/";
8942 odbpath += hp.vars[i].tag_name;
8943 break;
8944 }
8945
8946 /* check if variable is in setttins/names array */
8948 db_find_key(hDB, hkeyeq, "Settings/Names", &hkeynames);
8949 if (hkeynames) {
8950 /* extract variable name and Variables/<key> */
8951 mstrlcpy(str, hp.vars[i].tag_name.c_str(), sizeof(str));
8952 p = str + strlen(str) - 1;
8953 while (p > str && *p != ' ')
8954 p--;
8955 std::string key_name = p + 1;
8956 *p = 0;
8957
8958 std::string varname = str;
8959
8960 /* find key in single name array */
8962 for (k = 0; k < key.num_values; k++) {
8963 size = sizeof(str);
8965 if (equal_ustring(str, varname.c_str())) {
8966 //sprintf(odbpath, "/Equipment/%s/Variables/%s[%d]", event_name[i], key_name, k);
8967 odbpath = "";
8968 odbpath += "/Equipment/";
8969 odbpath += hp.vars[i].event_name;
8970 odbpath += "/Variables/";
8971 odbpath += key_name;
8972 odbpath += "[";
8973 odbpath += toString(k);
8974 odbpath += "]";
8975 break;
8976 }
8977 }
8978 } else {
8979 /* go through /variables/<name> entries */
8981 db_find_key(hDB, hkeyeq, "Variables", &hkeyvars);
8982 if (hkeyvars) {
8983 for (k = 0;; k++) {
8985
8986 if (!hkey)
8987 break;
8988
8989 /* find "settins/names <key>" for this key */
8990 db_get_key(hDB, hkey, &key);
8991
8992 /* find key in key_name array */
8993 std::string key_name = key.name;
8994
8995 std::string path;
8996 //sprintf(str, "Settings/Names %s", key_name);
8997 path += "Settings/Names ";
8998 path += key_name;
8999
9001 db_find_key(hDB, hkeyeq, path.c_str(), &hkeynames);
9002 if (hkeynames) {
9004 for (l = 0; l < key.num_values; l++) {
9005 size = sizeof(str);
9007 if (equal_ustring(str, hp.vars[i].tag_name.c_str())) {
9008 //sprintf(odbpath, "/Equipment/%s/Variables/%s[%d]", event_name[i], key_name, l);
9009 odbpath = "";
9010 odbpath += "/Equipment/";
9011 odbpath += hp.vars[i].event_name;
9012 odbpath += "/Variables/";
9013 odbpath += key_name;
9014 odbpath += "[";
9015 odbpath += toString(l);
9016 odbpath += "]";
9017 break;
9018 }
9019 }
9020 }
9021 }
9022 }
9023 }
9024
9025 break;
9026 }
9027 }
9028
9029 if (!hkeyeq) {
9030 db_find_key(hDB, 0, "/History/Links", &hkeyroot);
9031 if (hkeyroot) {
9032 for (j = 0;; j++) {
9033 HNDLE hkey;
9035
9036 if (!hkey)
9037 break;
9038
9039 KEY key;
9040 db_get_key(hDB, hkey, &key);
9041 if (equal_ustring(key.name, hp.vars[i].event_name.c_str())) {
9043 db_find_key(hDB, hkey, hp.vars[i].tag_name.c_str(), &hkey);
9044 if (hkey) {
9045 db_get_key(hDB, hkey, &key);
9047 if (key.num_values > 1) {
9048 odbpath += "[";
9049 odbpath += toString(var_index[i]);
9050 odbpath += "]";
9051 }
9052 break;
9053 }
9054 }
9055 }
9056 }
9057 }
9058 }
9059
9060 /* search alarm limits */
9061 upper_limit[i] = lower_limit[i] = -12345;
9062 db_find_key(hDB, 0, "Alarms/Alarms", &hkeyroot);
9063 if (odbpath.length() > 0 && hkeyroot) {
9064 for (j = 0;; j++) {
9065 HNDLE hkey;
9067
9068 if (!hkey)
9069 break;
9070
9071 size = sizeof(str);
9072 db_get_value(hDB, hkey, "Condition", str, &size, TID_STRING, TRUE);
9073
9074 if (strstr(str, odbpath.c_str())) {
9075 if (strchr(str, '<')) {
9076 p = strchr(str, '<') + 1;
9077 if (*p == '=')
9078 p++;
9079 if (hp.enable_factor) {
9080 lower_limit[i] = (hp.vars[i].factor * (atof(p) - hp.vars[i].voffset) + hp.vars[i].offset);
9081 } else {
9082 lower_limit[i] = atof(p);
9083 }
9084 }
9085 if (strchr(str, '>')) {
9086 p = strchr(str, '>') + 1;
9087 if (*p == '=')
9088 p++;
9089 if (hp.enable_factor) {
9090 upper_limit[i] = (hp.vars[i].factor * (atof(p) - hp.vars[i].voffset) + hp.vars[i].offset);
9091 } else {
9092 upper_limit[i] = atof(p);
9093 }
9094 }
9095 }
9096 }
9097 }
9098 } // loop over variables
9099
9100 //starttime = now - scale + toffset;
9101 //endtime = now + toffset;
9102
9103 starttime = xendtime - scale;
9104 endtime = xendtime;
9105
9106 //printf("now %d, scale %d, xendtime %d, starttime %d, endtime %d\n", now, scale, xendtime, starttime, endtime);
9107
9108 flags = READ_HISTORY_DATA;
9109 if (hp.show_run_markers)
9110 flags |= READ_HISTORY_RUNMARKER;
9111
9112 status = read_history(hp, /*hDB, hgroup, hpanel,*/ index, flags, starttime, endtime, scale/1000+1, hsdata);
9113
9114 if (status != HS_SUCCESS) {
9115 sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
9116 gdImageString(im, gdFontSmall, width / 2 - (strlen(str) * gdFontSmall->w) / 2, height / 2, str, red);
9117 goto error;
9118 }
9119
9121 char var_status[MAX_VARS][256];
9122
9123 for (int k=0; k<hsdata->nvars; k++) {
9124 int i = hsdata->odb_index[k];
9125
9126 if (i<0)
9127 continue;
9128
9129 if (index != -1 && index != i)
9130 continue;
9131
9132 n_point[i] = 0;
9133
9134 var_status[i][0] = 0;
9135 if (hsdata->status[k] == HS_UNDEFINED_VAR) {
9136 sprintf(var_status[i], "not found in history");
9137 continue;
9138 } else if (hsdata->status[k] != HS_SUCCESS) {
9139 sprintf(var_status[i], "hs_read() error %d, see messages", hsdata->status[k]);
9140 continue;
9141 }
9142
9143 int n_vp = 0;
9144 for (int j=0; j<hsdata->num_entries[k]; j++) {
9145 int xx = (int)(hsdata->t[k][j]);
9146 double yy = hsdata->v[k][j];
9147
9148 /* skip NaNs */
9149 if (ss_isnan(yy))
9150 continue;
9151
9152 /* skip INFs */
9153 if (!ss_isfin(yy))
9154 continue;
9155
9156 /* avoid overflow */
9157 if (yy > 1E30)
9158 yy = 1E30f;
9159
9160 /* apply factor and offset */
9161 if (hp.enable_factor) {
9162 yy = hp.vars[i].factor * (yy - hp.vars[i].voffset) + hp.vars[i].offset;
9163 }
9164
9165 /* calculate ymin and ymax */
9166 if ((i == 0 || index != -1) && n_vp == 0)
9167 ymin = ymax = yy;
9168 else {
9169 if (yy > ymax)
9170 ymax = yy;
9171 if (yy < ymin)
9172 ymin = yy;
9173 }
9174
9175 /* increment number of valid points */
9176
9177 x[i].push_back(xx);
9178 y[i].push_back(yy);
9179
9180 n_vp++;
9181
9182 } // loop over data
9183
9184 n_point[i] = n_vp;
9185
9186 assert(x[i].size() == y[i].size());
9187 }
9188
9189 //int flag;
9190 int xmaxm;
9191 int row;
9192 int xold;
9193 int yold;
9194 int aoffset;
9195 double yb1, yb2, yf1, yf2;
9196 int xs, ys;
9197 int x1, x2;
9198 int y1, y2;
9199 int xs_old;
9200 double ybase;
9201
9202 gdPoint poly[3];
9203
9204 if (ymin < minvalue)
9205 ymin = minvalue;
9206
9207 if (ymax > maxvalue)
9208 ymax = maxvalue;
9209
9210 /* check if ylow = 0 */
9211 if (index == -1) {
9212 //flag = 0;
9213 //size = sizeof(flag);
9214 //db_get_value(hDB, hkeypanel, "Zero ylow", &flag, &size, TID_BOOL, TRUE);
9215 if (hp.zero_ylow && ymin > 0)
9216 ymin = 0;
9217 }
9218
9219 /* if min and max too close together, switch to linear axis */
9220 if (logaxis && ymin > 0 && ymax > 0) {
9221 yb1 = pow(10, floor(log(ymin) / LN10));
9222 yf1 = floor(ymin / yb1);
9223 yb2 = pow(10, floor(log(ymax) / LN10));
9224 yf2 = floor(ymax / yb2);
9225
9226 if (yb1 == yb2 && yf1 == yf2)
9227 logaxis = 0;
9228 else {
9229 /* round down and up ymin and ymax */
9230 ybase = pow(10, floor(log(ymin) / LN10));
9231 ymin = (floor(ymin / ybase) * ybase);
9232 ybase = pow(10, floor(log(ymax) / LN10));
9233 ymax = ((floor(ymax / ybase) + 1) * ybase);
9234 }
9235 }
9236
9237 /* avoid negative limits for log axis */
9238 if (logaxis) {
9239 if (ymax <= 0)
9240 ymax = 1;
9241 if (ymin <= 0)
9242 ymin = 1E-12f;
9243 }
9244
9245 /* increase limits by 5% */
9246 if (ymin == 0 && ymax == 0) {
9247 ymin = -1;
9248 ymax = 1;
9249 } else {
9250 if (!logaxis) {
9251 ymax += (ymax - ymin) / 20.f;
9252
9253 if (ymin != 0)
9254 ymin -= (ymax - ymin) / 20.f;
9255 }
9256 }
9257
9258 /* avoid ymin == ymax */
9259 if (ymax == ymin) {
9260 if (logaxis) {
9261 ymax *= 2;
9262 ymin /= 2;
9263 } else {
9264 ymax += 10;
9265 ymin -= 10;
9266 }
9267 }
9268
9269 /* calculate X limits */
9270 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9271 //xmax = (double) (toffset / 3600.0);
9272 //xrange = xmax - xmin;
9273 //xrange = scale/3600.0;
9274
9275 /* caluclate required space for Y-axis */
9276 aoffset = vaxis(im, gdFontSmall, fgcol, gridcol, 0, 0, height, -3, -5, -7, -8, 0, ymin, ymax, logaxis);
9277 aoffset += 2;
9278
9279 x1 = aoffset;
9280 y1 = height - 20;
9281 x2 = width - 20;
9282 y2 = 20;
9283
9285
9286 /* draw axis frame */
9287 taxis(im, gdFontSmall, fgcol, gridcol, x1, y1, x2 - x1, width, 3, 5, 9, 10, 0, (double)starttime, (double)endtime);
9288
9289 vaxis(im, gdFontSmall, fgcol, gridcol, x1, y1, y1 - y2, -3, -5, -7, -8, x2 - x1, ymin, ymax, logaxis);
9290 gdImageLine(im, x1, y2, x2, y2, fgcol);
9291 gdImageLine(im, x2, y2, x2, y1, fgcol);
9292
9293 xs = ys = xold = yold = 0;
9294
9295 /* old code for run markers, new code is below */
9296
9297 /* write run markes if selected */
9298 if (/* DISABLES CODE */ (0) && hp.show_run_markers) {
9299
9300 const char* event_names[] = {
9301 "Run transitions",
9302 "Run transitions",
9303 0 };
9304
9305 const char* tag_names[] = {
9306 "State",
9307 "Run number",
9308 0 };
9309
9310 const int tag_indexes[] = {
9311 0,
9312 0,
9313 0 };
9314
9315 int num_entries[3];
9316 time_t *tbuf[3];
9317 double *dbuf[3];
9318 int st[3];
9319
9320 num_entries[0] = 0;
9321 num_entries[1] = 0;
9322
9323 status = mh->hs_read(starttime - scale, endtime, 0,
9324 2, event_names, tag_names, tag_indexes,
9325 num_entries, tbuf, dbuf, st);
9326
9327 //printf("read run info: status %d, entries %d %d\n", status, num_entries[0], num_entries[1]);
9328
9329 int n_marker = num_entries[0];
9330
9331 if (status == HS_SUCCESS && n_marker > 0 && n_marker < 100) {
9332 xs_old = -1;
9333 xmaxm = x1;
9334 for (j = 0; j < (int) n_marker; j++) {
9335 int col;
9336
9337 // explicit algebra manipulation to clarify computations:
9338
9339 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9340 //xrange = scale/3600.0;
9341 //time_t starttime = now - scale + toffset;
9342
9343 //x_marker = (int)(tbuf[1][j] - now);
9344 //xs = (int) ((x_marker / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9345 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9346 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - (-scale / 3600.0 + toffset / 3600.0)) / (scale/3600.0) * (x2 - x1) + x1 + 0.5);
9347 //xs = (int) (((tbuf[1][j] - now) - (-scale + toffset)) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9348 xs = (int) ((tbuf[1][j] - starttime) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9349
9350 if (xs < x1)
9351 continue;
9352 if (xs >= x2)
9353 continue;
9354
9355 double run_number = dbuf[1][j];
9356
9357 if (xs <= xs_old)
9358 xs = xs_old + 1;
9359 xs_old = xs;
9360
9361 if (dbuf[0][j] == 1)
9362 col = state_col[0];
9363 else if (dbuf[0][j] == 2)
9364 col = state_col[1];
9365 else if (dbuf[0][j] == 3)
9366 col = state_col[2];
9367 else
9368 col = state_col[0];
9369
9371
9372 sprintf(str, "%.0f", run_number);
9373
9374 if (dbuf[0][j] == STATE_RUNNING) {
9375 if (xs > xmaxm) {
9377 xmaxm = xs - 2 + gdFontSmall->h;
9378 }
9379 } else if (dbuf[0][j] == STATE_STOPPED) {
9380 if (xs + 2 - gdFontSmall->h > xmaxm) {
9382 xmaxm = xs - 1;
9383 }
9384 }
9385 }
9386 }
9387
9388 if (num_entries[0]) {
9389 free(tbuf[0]);
9390 free(dbuf[0]);
9391 tbuf[0] = NULL;
9392 dbuf[0] = NULL;
9393 }
9394
9395 if (num_entries[1]) {
9396 free(tbuf[1]);
9397 free(dbuf[1]);
9398 tbuf[1] = NULL;
9399 dbuf[1] = NULL;
9400 }
9401 }
9402
9403 /* write run markes if selected */
9404 if (hp.show_run_markers) {
9405
9406 int index_state = -1;
9407 int index_run_number = -1;
9408
9409 for (int k=0; k<hsdata->nvars; k++) {
9410 if (hsdata->odb_index[k] == -1)
9411 index_state = k;
9412
9413 if (hsdata->odb_index[k] == -2)
9415 }
9416
9417 bool ok = true;
9418
9419 if (ok)
9420 ok = (index_state >= 0) && (index_run_number >= 0);
9421
9422 if (ok)
9423 ok = (hsdata->status[index_state] == HS_SUCCESS);
9424
9425 if (ok)
9426 ok = (hsdata->status[index_run_number] == HS_SUCCESS);
9427
9428 if (/* DISABLES CODE */ (0) && ok)
9429 printf("read run info: indexes: %d, %d, status: %d, %d, entries: %d, %d\n", index_state, index_run_number, hsdata->status[index_state], hsdata->status[index_run_number], hsdata->num_entries[index_state], hsdata->num_entries[index_run_number]);
9430
9431 if (ok)
9432 ok = (hsdata->num_entries[index_state] == hsdata->num_entries[index_run_number]);
9433
9434 int n_marker = hsdata->num_entries[index_state];
9435
9436 if (ok && n_marker > 0 && n_marker < 100) {
9437 xs_old = -1;
9438 xmaxm = x1;
9439 for (j = 0; j < (int) n_marker; j++) {
9440 int col;
9441
9442 // explicit algebra manipulation to clarify computations:
9443
9444 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9445 //xrange = scale/3600.0;
9446 //time_t starttime = now - scale + toffset;
9447
9448 //x_marker = (int)(tbuf[1][j] - now);
9449 //xs = (int) ((x_marker / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9450 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9451 //xs = (int) (((tbuf[1][j] - now) / 3600.0 - (-scale / 3600.0 + toffset / 3600.0)) / (scale/3600.0) * (x2 - x1) + x1 + 0.5);
9452 //xs = (int) (((tbuf[1][j] - now) - (-scale + toffset)) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9453 xs = (int) ((hsdata->t[index_state][j] - starttime) / (scale/1.0) * (x2 - x1) + x1 + 0.5);
9454
9455 if (xs < x1)
9456 continue;
9457 if (xs >= x2)
9458 continue;
9459
9460 double run_number = hsdata->v[index_run_number][j];
9461
9462 if (xs <= xs_old)
9463 xs = xs_old + 1;
9464 xs_old = xs;
9465
9466 int state = (int)hsdata->v[index_state][j];
9467
9468 if (state == 1)
9469 col = state_col[0];
9470 else if (state == 2)
9471 col = state_col[1];
9472 else if (state == 3)
9473 col = state_col[2];
9474 else
9475 col = state_col[0];
9476
9478
9479 sprintf(str, "%.0f", run_number);
9480
9481 if (state == STATE_RUNNING) {
9482 if (xs > xmaxm) {
9484 xmaxm = xs - 2 + gdFontSmall->h;
9485 }
9486 } else if (state == STATE_STOPPED) {
9487 if (xs + 2 - gdFontSmall->h > xmaxm) {
9489 xmaxm = xs - 1;
9490 }
9491 }
9492 }
9493 }
9494 }
9495
9496 for (i = 0; i < (int)hp.vars.size(); i++) {
9497 if (index != -1 && index != i)
9498 continue;
9499
9500 /* draw alarm limits */
9501 if (lower_limit[i] != -12345) {
9502 if (logaxis) {
9503 if (lower_limit[i] <= 0)
9504 ys = y1;
9505 else
9506 ys = (int) (y1 - (log(lower_limit[i]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9507 } else {
9508 ys = (int) (y1 - (lower_limit[i] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9509 }
9510
9511 if (xs < 0)
9512 xs = 0;
9513 if (xs >= width)
9514 xs = width-1;
9515 if (ys < 0)
9516 ys = 0;
9517 if (ys >= height)
9518 ys = height-1;
9519
9520 if (ys > y2 && ys < y1) {
9522
9523 poly[0].x = x1;
9524 poly[0].y = ys;
9525 poly[1].x = x1 + 5;
9526 poly[1].y = ys;
9527 poly[2].x = x1;
9528 poly[2].y = ys - 5;
9529
9531 }
9532 }
9533 if (upper_limit[i] != -12345) {
9534 if (logaxis) {
9535 if (upper_limit[i] <= 0)
9536 ys = y1;
9537 else
9538 ys = (int) (y1 - (log(upper_limit[i]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9539 } else {
9540 ys = (int) (y1 - (upper_limit[i] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9541 }
9542
9543 if (xs < 0)
9544 xs = 0;
9545 if (xs >= width)
9546 xs = width-1;
9547 if (ys < 0)
9548 ys = 0;
9549 if (ys >= height)
9550 ys = height-1;
9551
9552 if (ys > y2 && ys < y1) {
9554
9555 poly[0].x = x1;
9556 poly[0].y = ys;
9557 poly[1].x = x1 + 5;
9558 poly[1].y = ys;
9559 poly[2].x = x1;
9560 poly[2].y = ys + 5;
9561
9563 }
9564 }
9565
9566 for (j = 0; j < (int) n_point[i]; j++) {
9567 //xmin = (double) (-scale / 3600.0 + toffset / 3600.0);
9568 //xrange = scale/3600.0;
9569 //xs = (int) (((x[i][j]-now) / 3600.0 - xmin) / xrange * (x2 - x1) + x1 + 0.5);
9570 //xs = (int) (((x[i][j] - now + scale - toffset) / 3600.0) / xrange * (x2 - x1) + x1 + 0.5);
9571 //xs = (int) (((x[i][j] - starttime) / 3600.0) / xrange * (x2 - x1) + x1 + 0.5);
9572 xs = (int) (((x[i][j] - starttime)/1.0) / (1.0*scale) * (x2 - x1) + x1 + 0.5);
9573
9574 if (logaxis) {
9575 if (y[i][j] <= 0)
9576 ys = y1;
9577 else
9578 ys = (int) (y1 - (log(y[i][j]) - log(ymin)) / (log(ymax) - log(ymin)) * (y1 - y2) + 0.5);
9579 } else {
9580 ys = (int) (y1 - (y[i][j] - ymin) / (ymax - ymin) * (y1 - y2) + 0.5);
9581 }
9582
9583 if (xs < 0)
9584 xs = 0;
9585 if (xs >= width)
9586 xs = width-1;
9587 if (ys < 0)
9588 ys = 0;
9589 if (ys >= height)
9590 ys = height-1;
9591
9592 if (j > 0)
9594 xold = xs;
9595 yold = ys;
9596 }
9597
9598 if (n_point[i] > 0) {
9599 poly[0].x = xs;
9600 poly[0].y = ys;
9601 poly[1].x = xs + 12;
9602 poly[1].y = ys - 6;
9603 poly[2].x = xs + 12;
9604 poly[2].y = ys + 6;
9605
9607 }
9608 }
9609
9610 if (labels) {
9611 for (i = 0; i < (int)hp.vars.size(); i++) {
9612 if (index != -1 && index != i)
9613 continue;
9614
9615 //str[0] = 0;
9616 //status = db_find_key(hDB, hkeypanel, "Label", &hkeydvar);
9617 //if (status == DB_SUCCESS) {
9618 // size = sizeof(str);
9619 // status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
9620 //}
9621
9622 std::string str = hp.vars[i].label.c_str();
9623
9624 if (str.empty()) {
9625 if (hp.enable_factor) {
9626 str = hp.vars[i].tag_name;
9627
9628 if (hp.vars[i].voffset > 0)
9629 str += msprintf(" - %G", hp.vars[i].voffset);
9630 else if (hp.vars[i].voffset < 0)
9631 str += msprintf(" + %G", -hp.vars[i].voffset);
9632
9633 if (hp.vars[i].factor != 1) {
9634 if (hp.vars[i].voffset == 0)
9635 str += msprintf(" * %+G", hp.vars[i].factor);
9636 else {
9637 str = msprintf("(%s) * %+G", str.c_str(), hp.vars[i].factor);
9638 }
9639 }
9640
9641 if (hp.vars[i].offset > 0)
9642 str += msprintf(" + %G", hp.vars[i].offset);
9643 else if (hp.vars[i].offset < 0)
9644 str += msprintf(" - %G", -hp.vars[i].offset);
9645
9646 } else {
9647 str = hp.vars[i].tag_name;
9648 }
9649 }
9650
9651 int k=0;
9652 for (int j=0; j<hsdata->nvars; j++)
9653 if (hsdata->odb_index[j] == i) {
9654 k = j;
9655 break;
9656 }
9657
9658 if (/* DISABLES CODE */ (0)) {
9659 printf("graph %d: odb index %d, n_point %d, num_entries %d, have_last_written %d %d, status %d, var_status [%s]\n", i, k, n_point[i], hsdata->num_entries[k], hsdata->have_last_written, (int)hsdata->last_written[k], hsdata->status[k], var_status[i]);
9660 }
9661
9662 if (hp.show_values) {
9663 char xstr[256];
9664 if (n_point[i] > 0) {
9665 sprintf(xstr," = %g", y[i][n_point[i]-1]);
9666 } else if (hsdata->num_entries[k] > 0) {
9667 sprintf(xstr," = all data is NaN or INF");
9668 } else if (hsdata->have_last_written) {
9669 if (hsdata->last_written[k]) {
9670 char ctimebuf[32];
9671 ctime_r(&hsdata->last_written[k], ctimebuf);
9672 sprintf(xstr," = last data %s", ctimebuf);
9673 // kill trailing '\n'
9674 char*s = strchr(xstr, '\n');
9675 if (s) *s=0;
9676 // clear the unnecessary error status report
9677 if (hsdata->status[k] == HS_UNDEFINED_VAR)
9678 var_status[i][0] = 0;
9679 } else {
9680 sprintf(xstr," = no data ever");
9681 }
9682 } else {
9683 sprintf(xstr," = no data");
9684 }
9685 str += xstr;
9686 }
9687
9688 if (strlen(var_status[i]) > 1) {
9689 str += msprintf(" (%s)", var_status[i]);
9690 }
9691
9692 row = index == -1 ? i : 0;
9693
9695 x1 + 10,
9696 y2 + 10 + row * (gdFontMediumBold->h + 10),
9697 x1 + 10 + str.length() * gdFontMediumBold->w + 10,
9698 y2 + 10 + row * (gdFontMediumBold->h + 10) +
9699 gdFontMediumBold->h + 2 + 2, white);
9700 gdImageRectangle(im, x1 + 10, y2 + 10 + row * (gdFontMediumBold->h + 10),
9701 x1 + 10 + str.length() * gdFontMediumBold->w + 10,
9702 y2 + 10 + row * (gdFontMediumBold->h + 10) +
9703 gdFontMediumBold->h + 2 + 2, curve_col[i]);
9704
9706 x1 + 10 + 5, y2 + 10 + 2 + row * (gdFontMediumBold->h + 10),
9707 (char*)str.c_str(),
9708 curve_col[i]);
9709 }
9710 }
9711
9713
9714 error:
9715
9716 /* generate GIF */
9717 gdImageInterlace(im, 1);
9718 gdImageGif(im, &gb);
9720 length = gb.size;
9721
9722 if (buffer == NULL) {
9723 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
9724 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
9725
9726 rr->rsprintf("Content-Type: image/gif\r\n");
9727 rr->rsprintf("Content-Length: %d\r\n", length);
9728 rr->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
9729 rr->rsprintf("Expires: Fri, 01-Jan-1983 00:00:00 GMT\r\n\r\n");
9730
9731 rr->rmemcpy(gb.data, length);
9732 } else {
9733 if (length > *buffer_size) {
9734 printf("return buffer too small\n");
9735 return;
9736 }
9737
9738 memcpy(buffer, gb.data, length);
9739 *buffer_size = length;
9740 }
9741}
virtual int hs_read(time_t start_time, time_t end_time, time_t interval, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int status[])=0
see hs_read(), returns HS_SUCCESS
#define HS_UNDEFINED_VAR
Definition midas.h:733
unsigned int DWORD
Definition mcstd.h:51
#define STATE_STOPPED
Definition midas.h:305
#define STATE_RUNNING
Definition midas.h:307
void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
Definition mgd.cxx:2471
void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:2299
gdImagePtr gdImageCreate(int sx, int sy)
Definition mgd.cxx:417
void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, const char *s, int color)
Definition mgd.cxx:877
void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:2307
void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:638
int w
Definition mgd.h:64
void gdImageStringUp(gdImagePtr im, gdFontPtr f, int x, int y, const char *s, int color)
Definition mgd.cxx:888
void gdImageDestroy(gdImagePtr im)
Definition mgd.cxx:439
gdFontPtr gdFontMediumBold
Definition mgd.cxx:408
int h
Definition mgd.h:65
gdFontPtr gdFontGiant
Definition mgd.cxx:409
void gdImageGif(gdImagePtr im, gdGifBuffer *buffer)
Definition mgd.cxx:1118
void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
Definition mgd.cxx:738
int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
Definition mgd.cxx:492
void gdImageInterlace(gdImagePtr im, int interlaceArg)
Definition mgd.cxx:2619
gdFontPtr gdFontSmall
Definition mgd.cxx:410
void gdImageColorTransparent(gdImagePtr im, int color)
Definition mgd.cxx:533
int ss_isnan(double x)
Definition system.cxx:7961
int ss_isfin(double x)
Definition system.cxx:7966
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4990
INT run_number[2]
Definition mana.cxx:246
#define LN10
Definition mhttpd.cxx:7628
#define MAX_VARS
Definition mhttpd.cxx:51
int vaxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double ymin, double ymax, BOOL logaxis)
Definition mhttpd.cxx:7906
void taxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int xr, int minor, int major, int text, int label, int grid, double xmin, double xmax)
Definition mhttpd.cxx:7785
#define READ_HISTORY_DATA
Definition mhttpd.cxx:8320
static MidasHistoryInterface * get_history(bool reset=false)
Definition mhttpd.cxx:8157
#define READ_HISTORY_RUNMARKER
Definition mhttpd.cxx:8321
MidasHistoryInterface * mh
INT k
Definition odbhist.cxx:40
Definition mgd.h:120
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_content_type()

std::string get_content_type ( const char filename)

Definition at line 1133 of file mhttpd.cxx.

1134{
1135 std::string ext_upper;
1136 const char* p = filename;
1137 const char* last_dot = NULL;
1138 for (; *p; p++) {
1139 if (*p == '.')
1140 last_dot = p;
1141 if (*p == DIR_SEPARATOR)
1142 last_dot = NULL;
1143 }
1144
1145 if (last_dot) {
1146 p = last_dot;
1147 for (; *p; p++)
1148 ext_upper += toupper(*p);
1149 }
1150
1151 //printf("filename: [%s], ext [%s]\n", filename, ext_upper.c_str());
1152
1153 std::string type = GetMimetype(ext_upper);
1154 if (type.length() > 0)
1155 return type;
1156
1157 cm_msg(MERROR, "get_content_type", "Unknown HTTP Content-Type for resource file \'%s\', file extension \'%s\'", filename, ext_upper.c_str());
1158
1159 return "text/plain";
1160}
static std::string GetMimetype(const std::string &ext)
Definition mhttpd.cxx:179
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_elog_url()

void get_elog_url ( char url,
int  len 
)
Here is the caller graph for this function:

◆ get_hist_last_written()

int get_hist_last_written ( MVOdb odb,
const char group,
const char panel,
time_t  endtime,
int  index,
int  want_all,
time_t plastwritten 
)

Definition at line 8521 of file mhttpd.cxx.

8522{
8523 //HNDLE hDB;
8524 int status;
8525
8526 time_t now = ss_time();
8527
8528 if (endtime == 0)
8529 endtime = now;
8530
8533
8534 //cm_get_experiment_database(&hDB, NULL);
8535
8536 HistPlot hp;
8538
8539 double tstart = ss_millitime();
8540
8541 int flags = READ_HISTORY_LAST_WRITTEN;
8542
8543 status = read_history(hp, /*hDB, group, panel,*/ index, flags, endtime, endtime, 0, hsdata);
8544
8545 if (status != HS_SUCCESS) {
8546 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8547 return status;
8548 }
8549
8550 if (!hsdata->have_last_written) {
8551 //sprintf(str, "Complete history failure, read_history() status %d, see messages", status);
8552 return HS_FILE_ERROR;
8553 }
8554
8555 int count = 0;
8557 time_t tmax = 0;
8558
8559 for (int k=0; k<hsdata->nvars; k++) {
8560 int i = hsdata->odb_index[k];
8561
8562 if (i<0)
8563 continue;
8564 if (index != -1 && index != i)
8565 continue;
8566
8567 time_t lw = hsdata->last_written[k];
8568
8569 if (lw==0) // no last_written for this variable, skip it.
8570 continue;
8571
8572 if (lw > endtime)
8573 lw = endtime; // just in case hs_get_last_written() returns dates in the "future" for this plot
8574
8575 if (lw > tmax)
8576 tmax = lw;
8577
8578 if (lw < tmin)
8579 tmin = lw;
8580
8581 count++;
8582
8583 //printf("odb index %d, last_written[%d] = %.0f, tmin %.0f, tmax %.0f, endtime %.0f\n", i, k, (double)lw, (double)tmin, (double)tmax, (double)endtime);
8584 }
8585
8586 if (count == 0) // all variables have no last_written
8587 return HS_FILE_ERROR;
8588
8589 if (want_all)
8590 *plastwritten = tmin; // all variables have data
8591 else
8592 *plastwritten = tmax; // at least one variable has data
8593
8594 //printf("tmin %.0f, tmax %.0f, endtime %.0f, last written %.0f\n", (double)tmin, (double)tmax, (double)endtime, (double)*plastwritten);
8595
8596 double tend = ss_millitime();
8597
8598 if (/* DISABLES CODE */ (0))
8599 printf("get_hist_last_written: elapsed time %f ms\n", tend-tstart);
8600
8601 return HS_SUCCESS;
8602}
#define HS_FILE_ERROR
Definition midas.h:728
DWORD ss_millitime()
Definition system.cxx:3393
#define READ_HISTORY_LAST_WRITTEN
Definition mhttpd.cxx:8322
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_history()

static MidasHistoryInterface * get_history ( bool  reset = false)
static

Definition at line 8157 of file mhttpd.cxx.

8158{
8159 int status;
8160 HNDLE hDB;
8161
8162 // history reconnect requested by watch callback?
8163
8164 if (gDoReloadHistory) {
8165 gDoReloadHistory = false;
8166 reset = true;
8167 }
8168
8169 // disconnect from previous history
8170
8171 if (reset && gMh) {
8172 gMh->hs_disconnect();
8173 delete gMh;
8174 gMh = NULL;
8175 gMhkey = 0;
8176 }
8177
8179 assert(status == CM_SUCCESS);
8180
8181 // setup a watch on history configuration
8182
8184 HNDLE hKey;
8185 gDoSetupHistoryWatch = false;
8186
8187 status = db_find_key(hDB, 0, "/Logger/History", &hKey);
8188 if (status == DB_SUCCESS)
8190
8191 status = db_find_key(hDB, 0, "/History/LoggerHistoryChannel", &hKey);
8192 if (status == DB_SUCCESS)
8194 }
8195
8196 // find out if ODB settings have changed and we need to connect to a different history channel
8197
8198 HNDLE hKey = 0;
8200 if (status != HS_SUCCESS)
8201 return gMh;
8202
8203 //printf("mh %p, hKey %d, mhkey %d\n", mh, hKey, mhkey);
8204
8205 if (gMh && hKey == gMhkey) // same channel as before
8206 return gMh;
8207
8208 if (gMh) {
8209 delete gMh;
8210 gMh = NULL;
8211 gMhkey = 0;
8212 }
8213
8215 if (status != HS_SUCCESS || gMh==NULL) {
8216 cm_msg(MERROR, "get_history", "Cannot configure history, hs_get_history() status %d", status);
8217 gMh = NULL;
8218 return NULL;
8219 }
8220
8221 gMhkey = hKey;
8222
8223 // cm_msg(MINFO, "get_history", "Reading history from channel \'%s\' type \'%s\'", mh->name, mh->type);
8224
8225 return gMh;
8226}
virtual int hs_disconnect()=0
disconnect from history, returns HS_SUCCESS
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13813
#define HS_GET_INACTIVE
Definition history.h:37
#define HS_GET_READER
Definition history.h:35
int hs_find_reader_channel(HNDLE hDB, HNDLE *hKeyOut, int debug_flag)
int hs_get_history(HNDLE hDB, HNDLE hKey, int flags, int debug_flag, MidasHistoryInterface **mh)
static void history_watch_callback(HNDLE hDB, HNDLE hKey, int index, void *info)
Definition mhttpd.cxx:8145
static HNDLE gMhkey
Definition mhttpd.cxx:8153
static bool gDoReloadHistory
Definition mhttpd.cxx:8143
static MidasHistoryInterface * gMh
Definition mhttpd.cxx:8152
static bool gDoSetupHistoryWatch
Definition mhttpd.cxx:8142
static BOOL verbose
Definition mhttpd.cxx:94
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_http_trace()

static MJsonNode * get_http_trace ( const MJsonNode *  params)
static

Definition at line 16175 of file mhttpd.cxx.

16176{
16177 if (!params) {
16178 MJSO *doc = MJSO::I();
16179 doc->D("get current value of mhttpd http_trace");
16180 doc->P(NULL, 0, "there are no input parameters");
16181 doc->R(NULL, MJSON_INT, "current value of http_trace");
16182 return doc;
16183 }
16184
16185 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16186}
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
static int http_trace
Definition mhttpd.cxx:433
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_resource_paths()

std::vector< std::string > get_resource_paths ( )

Definition at line 989 of file mhttpd.cxx.

990{
991 HNDLE hDB;
992 int status;
993
995
996 std::vector<std::string> paths;
997
998 // add /Experiment/Resources
999 std::string buf;
1000 status = db_get_value_string(hDB, 0, "/Experiment/Resources", 0, &buf, TRUE);
1001 if (status == DB_SUCCESS && buf.length() > 0)
1002 paths.push_back(buf);
1003
1004 // add "/Logger/History/IMAGE/History dir"
1005 paths.push_back(cm_get_history_path("IMAGE"));
1006
1007 // add /Logger/Data dir
1008 status = db_get_value_string(hDB, 0, "/Logger/Data dir", 0, &buf, TRUE);
1009 if (status == DB_SUCCESS && buf.length() > 0)
1010 paths.push_back(buf);
1011
1012 std::string cwd = ss_getcwd();
1013 if (!cwd.empty()) {
1014 paths.push_back(cwd + "/");
1015 paths.push_back(cwd + "/resources/");
1016 }
1017 paths.push_back(cm_get_path());
1018 paths.push_back(cm_get_path() + "resources/");
1019 char *m = getenv("MIDASSYS");
1020 if (m) {
1021 paths.push_back(std::string(m) + "/resources/");
1022 }
1023
1024 return paths;
1025}
std::string cm_get_history_path(const char *history_channel)
Definition midas.cxx:5843
std::string ss_getcwd()
Definition system.cxx:5770
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetMimetype()

static std::string GetMimetype ( const std::string &  ext)
static

Definition at line 179 of file mhttpd.cxx.

180{
181 if (gMimeTypesOdb) {
182 std::string mimetype;
183 gMimeTypesOdb->RS(ext.c_str(), &mimetype);
184 if (mimetype.length() > 0) {
185 //printf("GetMimetype: %s -> %s from ODB\n", ext.c_str(), mimetype.c_str());
186 return mimetype;
187 }
188 }
189
190 for (int i=0; gMimetypeTable[i].ext[0]; i++) {
191 if (ext == gMimetypeTable[i].ext) {
192 //printf("GetMimetype: %s -> %s from built-in table\n", ext.c_str(), gMimetypeTable[i].mimetype.c_str());
193 return gMimetypeTable[i].mimetype;
194 }
195 }
196
197 //printf("GetMimetype: %s -> not found\n", ext.c_str());
198 return "";
199}
static MVOdb * gMimeTypesOdb
Definition mhttpd.cxx:177
const MimetypeTableEntry gMimetypeTable[]
Definition mhttpd.cxx:128
std::string mimetype
Definition mhttpd.cxx:125
std::string ext
Definition mhttpd.cxx:124
Here is the caller graph for this function:

◆ GetTimeSec()

static double GetTimeSec ( )
static

Definition at line 374 of file mhttpd.cxx.

375{
376 struct timeval tv;
378 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
379}
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_decode_get()

static int handle_decode_get ( struct mg_connection nc,
const http_message msg,
const char uri,
const char query_string,
RequestTrace t 
)
static

Definition at line 14257 of file mhttpd.cxx.

14258{
14260
14261 decode_cookies(&cookies, msg);
14262
14263 // lock shared structures
14264
14265#ifdef HAVE_MONGOOSE6
14267 assert(status == SS_SUCCESS);
14268#endif
14269
14270 //t->fTimeLocked = GetTimeSec();
14271
14272 // prepare return buffer
14273
14274 Return *rr = new Return();
14275
14276 rr->zero();
14277
14278 // call midas
14279
14280 decode_get(rr, NULL, &cookies, uri, query_string, t);
14281
14282 if (trace_mg)
14283 printf("handle_decode_get: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14284
14286
14287 if (rr->return_length == -1) {
14288 delete rr;
14289#ifdef HAVE_MONGOOSE6
14290 //t->fTimeUnlocked = GetTimeSec();
14292#endif
14293 return RESPONSE_501;
14294 }
14295
14296 if (rr->return_length == 0)
14297 rr->return_length = strlen(rr->return_buffer);
14298
14299 //t->fTimeUnlocked = GetTimeSec();
14300
14301#ifdef HAVE_MONGOOSE6
14303#endif
14304
14305 mg_send(nc, rr->return_buffer, rr->return_length);
14306
14307 if (!strstr(rr->return_buffer, "Content-Length")) {
14308 // cannot do pipelined http if response generated by mhttpd
14309 // decode_get() has no Content-Length header.
14310 // must close the connection.
14312 }
14313
14314 t->fTimeSent = GetTimeSec();
14315
14316 delete rr;
14317
14318 return RESPONSE_SENT;
14319}
double fTimeSent
Definition mhttpd.cxx:390
double fTimeProcessed
Definition mhttpd.cxx:389
#define SS_SUCCESS
Definition midas.h:663
void mg_send(struct mg_connection *, const void *buf, int len)
unsigned long flags
Definition mongoose6.h:1276
#define MG_F_SEND_AND_CLOSE
Definition mongoose6.h:1288
INT ss_mutex_release(MUTEX_T *mutex)
Definition system.cxx:3157
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3037
static bool trace_mg
Definition mhttpd.cxx:13705
#define RESPONSE_501
Definition mhttpd.cxx:14255
void decode_cookies(Cookies *c, const http_message *msg)
Definition mhttpd.cxx:14206
void decode_get(Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:13195
#define RESPONSE_SENT
Definition mhttpd.cxx:14253
static double GetTimeSec()
Definition mhttpd.cxx:374
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_decode_post()

static int handle_decode_post ( struct mg_connection nc,
const http_message msg,
const char uri,
const char query_string,
RequestTrace t 
)
static

Definition at line 14724 of file mhttpd.cxx.

14725{
14726
14727 char boundary[256];
14728 boundary[0] = 0;
14729 const std::string ct = find_header_mg(msg, "Content-Type");
14730 if (ct.length() > 0) {
14731 const char* s = strstr(ct.c_str(), "boundary=");
14732 if (s)
14733 mstrlcpy(boundary, s+9, sizeof(boundary));
14734 }
14735
14736#ifdef HAVE_MONGOOSE616
14737 if (multithread_mg)
14738 return queue_decode_post(nc, msg, boundary, uri, query_string, t);
14739#endif
14740
14742
14743 decode_cookies(&cookies, msg);
14744
14745 const char* post_data = msg->body.p;
14746 int post_data_len = msg->body.len;
14747
14748 // lock shared strctures
14749
14750#ifdef HAVE_MONGOOSE6
14752 assert(status == SS_SUCCESS);
14753#endif
14754
14755 // prepare return buffer
14756
14757 Return* rr = new Return;
14758
14759 rr->zero();
14760
14761 //printf("post_data_len %d, data [%s], boundary [%s]\n", post_data_len, post_data, boundary);
14762
14763 decode_post(rr, NULL, (char*)post_data, boundary, post_data_len, &cookies, uri, t);
14764
14765 if (trace_mg)
14766 printf("handle_decode_post: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14767
14768 if (rr->return_length == -1) {
14769#ifdef HAVE_MONGOOSE6
14771#endif
14772 delete rr;
14773 return RESPONSE_501;
14774 }
14775
14776 if (rr->return_length == 0)
14777 rr->return_length = strlen(rr->return_buffer);
14778
14779#ifdef HAVE_MONGOOSE6
14781#endif
14782
14783 mg_send(nc, rr->return_buffer, rr->return_length);
14784
14785 if (!strstr(rr->return_buffer, "Content-Length")) {
14786 // cannot do pipelined http if response generated by mhttpd
14787 // decode_get() has no Content-Length header.
14788 // must close the connection.
14790 }
14791
14792 delete rr;
14793
14794 return RESPONSE_SENT;
14795}
void zero()
Definition mhttpd.cxx:547
struct mg_str body
Definition mongoose6.h:2094
void decode_post(Return *rr, const char *header, const char *string, const char *boundary, int length, const Cookies *c, const char *url, RequestTrace *t)
Definition mhttpd.cxx:13233
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_event_mg()

static void handle_event_mg ( struct mg_connection nc,
int  ev,
void ev_data 
)
static

Definition at line 14172 of file mhttpd.cxx.

14173{
14174 struct mbuf *io = &nc->recv_mbuf;
14175 switch (ev) {
14176 case MG_EV_POLL: // periodic call from loop_mg() via mg_mgr_poll()
14177 break;
14178 case MG_EV_ACCEPT:
14179 if (trace_mg)
14180 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> accept\n", nc, ev, ev_data);
14181 break;
14182 case MG_EV_RECV:
14183 if (trace_mg)
14184 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> recv %d, buffered %d bytes\n", nc, ev, ev_data, *(int*)ev_data, (int)io->len);
14185#if 0
14186 // This event handler implements simple TCP echo server
14187 mg_send(nc, io->buf, io->len); // Echo received data back
14188 mbuf_remove(io, io->len); // Discard data from recv buffer
14189#endif
14190 break;
14191 case MG_EV_SEND:
14192 if (trace_mg)
14193 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> send %d bytes\n", nc, ev, ev_data, *(int*)ev_data);
14194 break;
14195 case MG_EV_CLOSE:
14196 if (trace_mg)
14197 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> close\n", nc, ev, ev_data);
14198 break;
14199 default:
14200 if (trace_mg)
14201 printf("handle_event_mg: nc %p, ev %d, ev_data %p\n", nc, ev, ev_data);
14202 break;
14203 }
14204}
void mbuf_remove(struct mbuf *, size_t data_size)
#define MG_EV_RECV
Definition mongoose6.h:1222
struct mbuf recv_mbuf
Definition mongoose6.h:1255
#define MG_EV_POLL
Definition mongoose6.h:1219
#define MG_EV_SEND
Definition mongoose6.h:1223
#define MG_EV_CLOSE
Definition mongoose6.h:1224
#define MG_EV_ACCEPT
Definition mongoose6.h:1220
Here is the call graph for this function:

◆ handle_http_get()

static int handle_http_get ( struct mg_connection nc,
const http_message msg,
const char uri,
RequestTrace t 
)
static

Definition at line 14797 of file mhttpd.cxx.

14798{
14799 std::string query_string = mgstr(&msg->query_string);
14800
14801 if (trace_mg||verbose_mg)
14802 printf("handle_http_get: uri [%s], query [%s]\n", uri, query_string.c_str());
14803
14804 if (query_string == "mjsonrpc_schema") {
14805 MJsonNode* s = mjsonrpc_get_schema();
14806 std::string reply = s->Stringify();
14807 delete s;
14808
14809 int reply_length = reply.length();
14810
14811 const std::string origin_header = find_header_mg(msg, "Origin");
14812
14813 std::string headers;
14814 headers += "HTTP/1.1 200 OK\n";
14815 if (origin_header.length() > 0)
14816 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14817 else
14818 headers += "Access-Control-Allow-Origin: *\n";
14819 headers += "Access-Control-Allow-Credentials: true\n";
14820 headers += "Content-Length: " + toString(reply_length) + "\n";
14821 headers += "Content-Type: application/json\n";
14822 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14823
14824 //printf("sending headers: %s\n", headers.c_str());
14825 //printf("sending reply: %s\n", reply.c_str());
14826
14827 std::string send = headers + "\n" + reply;
14828
14830
14831 mg_send(nc, send.c_str(), send.length());
14832
14833 t->fTimeSent = GetTimeSec();
14834
14835 return RESPONSE_SENT;
14836 }
14837
14838 if (query_string == "mjsonrpc_schema_text") {
14839 MJsonNode* s = mjsonrpc_get_schema();
14840 std::string reply = mjsonrpc_schema_to_text(s);
14841 delete s;
14842
14843 int reply_length = reply.length();
14844
14845 const std::string origin_header = find_header_mg(msg, "Origin");
14846
14847 std::string headers;
14848 headers += "HTTP/1.1 200 OK\n";
14849 if (origin_header.length() > 0)
14850 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14851 else
14852 headers += "Access-Control-Allow-Origin: *\n";
14853 headers += "Access-Control-Allow-Credentials: true\n";
14854 headers += "Content-Length: " + toString(reply_length) + "\n";
14855 headers += "Content-Type: text/plain\n";
14856 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14857
14858 //printf("sending headers: %s\n", headers.c_str());
14859 //printf("sending reply: %s\n", reply.c_str());
14860
14861 std::string send = headers + "\n" + reply;
14862
14864
14865 mg_send(nc, send.c_str(), send.length());
14866
14867 t->fTimeSent = GetTimeSec();
14868
14869 return RESPONSE_SENT;
14870 }
14871
14872#ifdef HAVE_MONGOOSE616
14873 if (multithread_mg)
14874 return queue_decode_get(nc, msg, uri, query_string.c_str(), t);
14875#endif
14876
14877 return handle_decode_get(nc, msg, uri, query_string.c_str(), t);
14878}
MJsonNode * mjsonrpc_get_schema()
std::string mjsonrpc_schema_to_text(const MJsonNode *schema)
struct mg_str query_string
Definition mongoose6.h:2087
static bool verbose_mg
Definition mhttpd.cxx:13704
static int handle_decode_get(struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:14257
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_http_message()

static void handle_http_message ( struct mg_connection nc,
http_message msg 
)
static

Definition at line 15071 of file mhttpd.cxx.

15072{
15073 std::string method = mgstr(&msg->method);
15074 std::string query_string = mgstr(&msg->query_string);
15075 std::string uri_encoded = mgstr(&msg->uri);
15076 std::string uri = UrlDecode(uri_encoded.c_str());
15077
15078 if (trace_mg)
15079 printf("handle_http_message: method [%s] uri [%s] proto [%s]\n", method.c_str(), uri.c_str(), mgstr(&msg->proto).c_str());
15080
15081 RequestTrace* t = new RequestTrace;
15083 t->fMethod = method;
15084 t->fUri = uri;
15085 t->fQuery = query_string;
15086
15087 // process OPTIONS for Cross-origin (CORS) preflight request
15088 // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
15089 if (method == "OPTIONS" && query_string == "mjsonrpc" && mg_get_http_header(msg, "Access-Control-Request-Method") != NULL) {
15090 handle_http_options_cors(nc, msg, t);
15091 t->fCompleted = true;
15093 return;
15094 }
15095
15097 std::string username = check_digest_auth(msg, gAuthMg);
15098
15099 // Cannot re-read the password file - it is not thread safe to do so
15100 // unless I lock gAuthMg for each call check_digest_auth() and if I do so,
15101 // I will serialize (single-thread) all the http requests and defeat
15102 // the whole point of multithreading the web server. K.O.
15103 //
15105 //if (username.length() < 1) {
15106 // bool ok = read_passwords(&gAuthMg);
15107 // if (ok)
15108 // username = check_digest_auth(msg, &gAuthMg);
15109 //}
15110
15111 if (trace_mg)
15112 printf("handle_http_message: auth user: \"%s\"\n", username.c_str());
15113
15114 if (username.length() == 0) {
15115 if (trace_mg||verbose_mg)
15116 printf("handle_http_message: method [%s] uri [%s] query [%s] proto [%s], sending auth request for realm \"%s\"\n", method.c_str(), uri.c_str(), query_string.c_str(), mgstr(&msg->proto).c_str(), gAuthMg->realm.c_str());
15117
15119 t->fCompleted = true;
15121 return;
15122 }
15123 t->fAuthOk = true;
15124 } else {
15125 t->fAuthOk = true;
15126 }
15127
15128#ifdef HAVE_MONGOOSE616
15129 if (gProxyOdb && starts_with(uri, "/proxy/")) {
15130 std::string::size_type p1 = uri.find("/", 1);
15131 if (p1 == uri.length()-1) {
15132 std::string response = "404 Not Found (Proxy name is missing)";
15133 mg_send_head(nc, 404, response.length(), NULL);
15134 mg_send(nc, response.c_str(), response.length());
15135 delete t;
15136 return;
15137 }
15138 std::string::size_type p2 = uri.find("/", p1+1);
15139 if (p2 == std::string::npos) {
15140 std::string response = "404 Not Found (Proxy URL should end with a slash)";
15141 mg_send_head(nc, 404, response.length(), NULL);
15142 mg_send(nc, response.c_str(), response.length());
15143 delete t;
15144 return;
15145 }
15146 std::string p = uri.substr(p1+1, p2-p1-1);
15147 //printf("uri [%s], p1: %d, p2: %d, substr: [%s]\n", uri.c_str(), (int)p1, (int)p2, p.c_str());
15148 if (p.length() < 1) {
15149 std::string response = "404 Not Found (Double-slash or Proxy name is too short)";
15150 mg_send_head(nc, 404, response.length(), NULL);
15151 mg_send(nc, response.c_str(), response.length());
15152 delete t;
15153 return;
15154 }
15155 std::string destination;
15156 gProxyOdb->RS(p.c_str(), &destination);
15157 if (destination.length() < 1) {
15158 std::string response = "404 Not Found (Proxy not found in ODB)";
15159 mg_send_head(nc, 404, response.length(), NULL);
15160 mg_send(nc, response.c_str(), response.length());
15161 delete t;
15162 return;
15163 } else if (destination[0] == '#') {
15164 std::string response = "404 Not Found (Proxy commented-out in ODB)";
15165 mg_send_head(nc, 404, response.length(), NULL);
15166 mg_send(nc, response.c_str(), response.length());
15167 delete t;
15168 return;
15169 } else if (ends_with_char(destination, '/')) {
15170 std::string response = "404 Not Found (Proxy address should not end with a slash)";
15171 mg_send_head(nc, 404, response.length(), NULL);
15172 mg_send(nc, response.c_str(), response.length());
15173 delete t;
15174 return;
15175 } else if (!starts_with(destination, "http")) {
15176 std::string response = "404 Not Found (Proxy address does not start with http";
15177 mg_send_head(nc, 404, response.length(), NULL);
15178 mg_send(nc, response.c_str(), response.length());
15179 delete t;
15180 return;
15181 } else {
15182 std::string m;
15183 m += "/proxy";
15184 m += "/";
15185 m += p;
15186 mg_str mount = mg_mk_str(m.c_str());
15188 if (verbose_mg||trace_mg) {
15189 printf("proxy: uri [%s] mount [%s] upstream [%s]\n", uri.c_str(), mgstr(&mount).c_str(), mgstr(&upstream).c_str());
15190 }
15192 delete t;
15193 return;
15194 }
15195 }
15196#endif
15197
15198 int response = RESPONSE_501;
15199
15200 if (method == "GET")
15201 response = handle_http_get(nc, msg, uri.c_str(), t);
15202 else if (method == "POST")
15203 response = handle_http_post(nc, msg, uri.c_str(), t);
15204
15205 if (response == RESPONSE_501) {
15206 if (trace_mg||verbose_mg)
15207 printf("handle_http_message: sending 501 Not Implemented error\n");
15208
15209 std::string response = "501 Not Implemented";
15210 mg_send_head(nc, 501, response.length(), NULL); // 501 Not Implemented
15211 mg_send(nc, response.c_str(), response.length());
15212 }
15213
15214 if (response != RESPONSE_QUEUED) {
15215 t->fCompleted = true;
15217 }
15218}
std::string realm
Definition mhttpd.cxx:13724
void AddTraceMTS(RequestTrace *t)
Definition mhttpd.cxx:461
std::string fQuery
Definition mhttpd.cxx:394
std::string fMethod
Definition mhttpd.cxx:392
std::string fUri
Definition mhttpd.cxx:393
bool fCompleted
Definition mhttpd.cxx:391
double fTimeReceived
Definition mhttpd.cxx:386
void mg_send_head(struct mg_connection *n, int status_code, int64_t content_length, const char *extra_headers)
struct mg_str uri
Definition mongoose6.h:2072
struct mg_str method
Definition mongoose6.h:2071
struct mg_str proto
Definition mongoose6.h:2073
struct mg_str mg_mk_str(const char *s)
static int handle_http_post(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14880
static bool mongoose_passwords_enabled(const struct mg_connection *nc)
static std::string check_digest_auth(struct http_message *hm, Auth *auth)
Definition mhttpd.cxx:13892
static std::string UrlDecode(const char *p)
Definition mhttpd.cxx:841
bool starts_with(const std::string &s1, const char *s2)
Definition mhttpd.cxx:4427
#define RESPONSE_QUEUED
Definition mhttpd.cxx:14254
static int handle_http_get(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14797
static RequestTraceBuf * gTraceBuf
Definition mhttpd.cxx:504
static void xmg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
Definition mhttpd.cxx:13786
static void handle_http_options_cors(struct mg_connection *nc, const http_message *msg, RequestTrace *t)
Definition mhttpd.cxx:15001
static Auth * gAuthMg
Definition mhttpd.cxx:13752
bool ends_with_char(const std::string &s, char c)
Definition midas.cxx:403
Here is the call graph for this function:

◆ handle_http_options_cors()

static void handle_http_options_cors ( struct mg_connection nc,
const http_message msg,
RequestTrace t 
)
static

Definition at line 15001 of file mhttpd.cxx.

15002{
15003 //
15004 // JSON-RPC CORS pre-flight request, see
15005 // https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
15006 //
15007 // OPTIONS /resources/post-here/ HTTP/1.1
15008 // Host: bar.other
15009 // User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
15010 // Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
15011 // Accept-Language: en-us,en;q=0.5
15012 // Accept-Encoding: gzip,deflate
15013 // Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
15014 // Connection: keep-alive
15015 // Origin: http://foo.example
15016 // Access-Control-Request-Method: POST
15017 // Access-Control-Request-Headers: X-PINGOTHER
15018 //
15019 // HTTP/1.1 200 OK
15020 // Date: Mon, 01 Dec 2008 01:15:39 GMT
15021 // Server: Apache/2.0.61 (Unix)
15022 // Access-Control-Allow-Origin: http://foo.example
15023 // Access-Control-Allow-Methods: POST, GET, OPTIONS
15024 // Access-Control-Allow-Headers: X-PINGOTHER
15025 // Access-Control-Max-Age: 1728000
15026 // Vary: Accept-Encoding, Origin
15027 // Content-Encoding: gzip
15028 // Content-Length: 0
15029 // Keep-Alive: timeout=2, max=100
15030 // Connection: Keep-Alive
15031 // Content-Type: text/plain
15032 //
15033
15034 const std::string origin_header = find_header_mg(msg, "Origin");
15035
15036 if (trace_mg||verbose_mg)
15037 printf("handle_http_options_cors: origin [%s]\n", origin_header.c_str());
15038
15039 std::string headers;
15040 headers += "HTTP/1.1 200 OK\n";
15041 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
15042 if (origin_header.length() > 0)
15043 headers += "Access-Control-Allow-Origin: " + origin_header + "\n";
15044 else
15045 headers += "Access-Control-Allow-Origin: *\n";
15046 headers += "Access-Control-Allow-Headers: Content-Type\n";
15047 headers += "Access-Control-Allow-Credentials: true\n";
15048 headers += "Access-Control-Max-Age: 120\n";
15049 headers += "Content-Length: 0\n";
15050 headers += "Content-Type: text/plain\n";
15051 //printf("sending headers: %s\n", headers.c_str());
15052 //printf("sending reply: %s\n", reply.c_str());
15053
15054 std::string send = headers + "\n";
15055
15057
15058 mg_send(nc, send.c_str(), send.length());
15059
15060 t->fTimeSent = GetTimeSec();
15061}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_http_post()

static int handle_http_post ( struct mg_connection nc,
const http_message msg,
const char uri,
RequestTrace t 
)
static

Definition at line 14880 of file mhttpd.cxx.

14881{
14882 std::string query_string = mgstr(&msg->query_string);
14883 std::string post_data = mgstr(&msg->body);
14884
14885 if (trace_mg||verbose_mg)
14886 printf("handle_http_post: uri [%s], query [%s], post data %d bytes\n", uri, query_string.c_str(), (int)post_data.length());
14887
14888 if (query_string == "mjsonrpc") {
14889 const std::string origin_header = find_header_mg(msg, "Origin");
14890 const std::string ctype_header = find_header_mg(msg, "Content-Type");
14891
14892 if (strstr(ctype_header.c_str(), "application/json") == NULL) {
14893 std::string headers;
14894 headers += "HTTP/1.1 415 Unsupported Media Type\n";
14895 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14896
14897 //printf("sending headers: %s\n", headers.c_str());
14898 //printf("sending reply: %s\n", reply.c_str());
14899
14900 std::string send = headers + "\n";
14901
14903
14904 mg_send(nc, send.c_str(), send.length());
14905
14906 t->fTimeSent = GetTimeSec();
14907
14908 return RESPONSE_SENT;
14909 }
14910
14911#ifdef HAVE_MONGOOSE616
14912 if (multithread_mg)
14913 return queue_mjsonrpc(nc, origin_header, post_data, t);
14914#endif
14915
14916 //printf("post body: %s\n", post_data.c_str());
14917
14918 t->fRPC = post_data;
14919
14920#ifdef HAVE_MONGOOSE6
14922 assert(status == SS_SUCCESS);
14923#endif
14924
14925 //t->fTimeLocked = GetTimeSec();
14926
14927 MJsonNode* reply = mjsonrpc_decode_post_data(post_data.c_str());
14928
14929 //t->fTimeUnlocked = GetTimeSec();
14930
14931#ifdef HAVE_MONGOOSE6
14933#endif
14934
14935 if (reply->GetType() == MJSON_ARRAYBUFFER) {
14936 const char* ptr;
14937 size_t size;
14938 reply->GetArrayBuffer(&ptr, &size);
14939
14940 std::string headers;
14941 headers += "HTTP/1.1 200 OK\n";
14942 if (origin_header.length() > 0)
14943 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14944 else
14945 headers += "Access-Control-Allow-Origin: *\n";
14946 headers += "Access-Control-Allow-Credentials: true\n";
14947 headers += "Content-Length: " + toString(size) + "\n";
14948 headers += "Content-Type: application/octet-stream\n";
14949 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14950
14951 //printf("sending headers: %s\n", headers.c_str());
14952 //printf("sending reply: %s\n", reply_string.c_str());
14953
14954 std::string send = headers + "\n";
14955
14957
14958 mg_send(nc, send.c_str(), send.length());
14959 mg_send(nc, ptr, size);
14960
14961 t->fTimeSent = GetTimeSec();
14962
14963 delete reply;
14964
14965 return RESPONSE_SENT;
14966 }
14967
14968 std::string reply_string = reply->Stringify();
14969 int reply_length = reply_string.length();
14970
14971 std::string headers;
14972 headers += "HTTP/1.1 200 OK\n";
14973 if (origin_header.length() > 0)
14974 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14975 else
14976 headers += "Access-Control-Allow-Origin: *\n";
14977 headers += "Access-Control-Allow-Credentials: true\n";
14978 headers += "Content-Length: " + toString(reply_length) + "\n";
14979 headers += "Content-Type: application/json\n";
14980 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14981
14982 //printf("sending headers: %s\n", headers.c_str());
14983 //printf("sending reply: %s\n", reply_string.c_str());
14984
14985 std::string send = headers + "\n" + reply_string;
14986
14988
14989 mg_send(nc, send.c_str(), send.length());
14990
14991 t->fTimeSent = GetTimeSec();
14992
14993 delete reply;
14994
14995 return RESPONSE_SENT;
14996 }
14997
14998 return handle_decode_post(nc, msg, uri, query_string.c_str(), t);
14999}
std::string fRPC
Definition mhttpd.cxx:395
MJsonNode * mjsonrpc_decode_post_data(const char *post_data)
static int handle_decode_post(struct mg_connection *nc, const http_message *msg, const char *uri, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:14724
Here is the call graph for this function:
Here is the caller graph for this function:

◆ haxis()

void haxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  xmin,
double  xmax 
)

Definition at line 7632 of file mhttpd.cxx.

7635{
7638 char str[80];
7639 double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7640
7641 if (xmax <= xmin || width <= 0)
7642 return;
7643
7644 /* use 5 as min tick distance */
7645 dx = (xmax - xmin) / (double) (width / 5);
7646
7647 frac_dx = modf(log(dx) / LN10, &int_dx);
7648 if (frac_dx < 0) {
7649 frac_dx += 1;
7650 int_dx -= 1;
7651 }
7652
7653 tick_base = frac_dx < LOG2 ? 1 : frac_dx < LOG5 ? 2 : 3;
7655
7656 /* rounding up of dx, label_dx */
7657 dx = pow(10, int_dx) * base[tick_base];
7658 major_dx = pow(10, int_dx) * base[major_base];
7660
7661 /* number of significant digits */
7662 if (xmin == 0)
7663 n_sig1 = 0;
7664 else
7665 n_sig1 = (int) floor(log(fabs(xmin)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7666
7667 if (xmax == 0)
7668 n_sig2 = 0;
7669 else
7670 n_sig2 =
7671 (int) floor(log(fabs(xmax)) / LN10) - (int) floor(log(fabs(label_dx)) / LN10) + 1;
7672
7673 n_sig1 = MAX(n_sig1, n_sig2);
7674 n_sig1 = MAX(n_sig1, 4);
7675
7676 /* determination of maximal width of labels */
7677 sprintf(str, "%1.*lG", n_sig1, floor(xmin / dx) * dx);
7678 maxwidth = font->h / 2 * strlen(str);
7679 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx);
7680 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7681 sprintf(str, "%1.*lG", n_sig1, floor(xmax / dx) * dx + label_dx);
7682 maxwidth = MAX(maxwidth, font->h / 2 * strlen(str));
7683
7684 /* increasing label_dx, if labels would overlap */
7685 while (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7686 label_base++;
7687 label_dx = pow(10, int_dx) * base[label_base];
7688 if (label_base % 3 == 2 && major_base % 3 == 1) {
7689 major_base++;
7690 major_dx = pow(10, int_dx) * base[major_base];
7691 }
7692 }
7693
7694 x_act = floor(xmin / dx) * dx;
7695
7696 gdImageLine(im, x1, y1, x1 + width, y1, col);
7697
7698 do {
7699 x_screen = (x_act - xmin) / (xmax - xmin) * width + x1;
7700 xs = (int) (x_screen + 0.5);
7701
7702 if (x_screen > x1 + width + 0.001)
7703 break;
7704
7705 if (x_screen >= x1) {
7706 if (fabs(floor(x_act / major_dx + 0.5) - x_act / major_dx) <
7707 dx / major_dx / 10.0) {
7708
7709 if (fabs(floor(x_act / label_dx + 0.5) - x_act / label_dx) <
7710 dx / label_dx / 10.0) {
7711 /* label tick mark */
7712 gdImageLine(im, xs, y1, xs, y1 + text, col);
7713
7714 /* grid line */
7715 if (grid != 0 && xs > x1 && xs < x1 + width)
7716 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7717
7718 /* label */
7719 if (label != 0) {
7720 sprintf(str, "%1.*lG", n_sig1, x_act);
7721 gdImageString(im, font, (int) xs - font->w * strlen(str) / 2,
7722 y1 + label, str, col);
7723 }
7724 } else {
7725 /* major tick mark */
7726 gdImageLine(im, xs, y1, xs, y1 + major, col);
7727
7728 /* grid line */
7729 if (grid != 0 && xs > x1 && xs < x1 + width)
7730 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7731 }
7732
7733 } else
7734 /* minor tick mark */
7735 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7736
7737 }
7738
7739 x_act += dx;
7740
7741 /* supress 1.23E-17 ... */
7742 if (fabs(x_act) < dx / 100)
7743 x_act = 0;
7744
7745 } while (1);
7746}
#define MAX(a, b)
Definition midas.h:509
#define LOG2
Definition mhttpd.cxx:7629
#define LOG5
Definition mhttpd.cxx:7630
static te_expr * base(state *s)
Definition tinyexpr.c:357
Here is the call graph for this function:
Here is the caller graph for this function:

◆ history_watch_callback()

static void history_watch_callback ( HNDLE  hDB,
HNDLE  hKey,
int  index,
void info 
)
static

Definition at line 8145 of file mhttpd.cxx.

8146{
8147 //printf("history_watch_callback %d %d %d\n", hDB, hKey, index);
8148 gDoReloadHistory = true;
8149 cm_msg(MINFO, "history_watch_callback", "History configuration may have changed, will reconnect");
8150}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_elog_odb()

void init_elog_odb ( )

Definition at line 1978 of file mhttpd.cxx.

1979{
1980 HNDLE hDB;
1981 int size;
1982 HNDLE hkey;
1984
1986 std::string external_elog_url;
1987
1988 size = sizeof(external_elog);
1989 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
1990 db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
1991
1994 size = sizeof(BOOL);
1995 db_get_value(hDB, 0, "/Elog/Allow delete", &allow_delete, &size, TID_BOOL, TRUE);
1996 db_get_value(hDB, 0, "/Elog/Allow edit", &allow_edit, &size, TID_BOOL, TRUE);
1997 //db_get_value(hDB, 0, "/Elog/Display run number", &display_run_number, &size, TID_BOOL, TRUE);
1998
1999 if (db_find_key(hDB, 0, "/Elog/Buttons", &hkey) != DB_SUCCESS) {
2000 const char def_button[][NAME_LENGTH] = { "8h", "24h", "7d" };
2001 db_set_value(hDB, 0, "/Elog/Buttons", def_button, NAME_LENGTH*3, 3, TID_STRING);
2002 }
2003
2004
2005 /* get type list from ODB */
2006 size = 20 * NAME_LENGTH;
2007 if (db_find_key(hDB, 0, "/Elog/Types", &hkey) != DB_SUCCESS) {
2008 db_set_value(hDB, 0, "/Elog/Types", default_type_list, NAME_LENGTH * 20, 20, TID_STRING);
2009 }
2010
2011 /* get system list from ODB */
2012 size = 20 * NAME_LENGTH;
2013 if (db_find_key(hDB, 0, "/Elog/Systems", &hkey) != DB_SUCCESS)
2014 db_set_value(hDB, 0, "/Elog/Systems", default_system_list, NAME_LENGTH * 20, 20, TID_STRING);
2015}
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
static const char default_type_list[20][NAME_LENGTH]
Definition mhttpd.cxx:99
static const char default_system_list[20][NAME_LENGTH]
Definition mhttpd.cxx:114
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_menu_buttons()

void init_menu_buttons ( MVOdb odb)

Definition at line 1890 of file mhttpd.cxx.

1891{
1892 HNDLE hDB;
1895 int size = sizeof(true_value);
1897 db_get_value(hDB, 0, "/Experiment/Menu/Status", &true_value, &size, TID_BOOL, TRUE);
1898 db_get_value(hDB, 0, "/Experiment/Menu/Start", &false_value, &size, TID_BOOL, TRUE);
1899 db_get_value(hDB, 0, "/Experiment/Menu/Transition", &true_value, &size, TID_BOOL, TRUE);
1900 db_get_value(hDB, 0, "/Experiment/Menu/ODB", &true_value, &size, TID_BOOL, TRUE);
1901 db_get_value(hDB, 0, "/Experiment/Menu/OldODB", &true_value, &size, TID_BOOL, TRUE);
1902 db_get_value(hDB, 0, "/Experiment/Menu/Messages", &true_value, &size, TID_BOOL, TRUE);
1903 db_get_value(hDB, 0, "/Experiment/Menu/Chat", &true_value, &size, TID_BOOL, TRUE);
1904 db_get_value(hDB, 0, "/Experiment/Menu/Elog", &true_value, &size, TID_BOOL, TRUE);
1905 db_get_value(hDB, 0, "/Experiment/Menu/Alarms", &true_value, &size, TID_BOOL, TRUE);
1906 db_get_value(hDB, 0, "/Experiment/Menu/Programs", &true_value, &size, TID_BOOL, TRUE);
1907 db_get_value(hDB, 0, "/Experiment/Menu/Buffers", &true_value, &size, TID_BOOL, TRUE);
1908 db_get_value(hDB, 0, "/Experiment/Menu/History", &true_value, &size, TID_BOOL, TRUE);
1909 db_get_value(hDB, 0, "/Experiment/Menu/OldHistory", &true_value, &size, TID_BOOL, TRUE);
1910 db_get_value(hDB, 0, "/Experiment/Menu/MSCB", &true_value, &size, TID_BOOL, TRUE);
1911 db_get_value(hDB, 0, "/Experiment/Menu/Sequencer", &true_value, &size, TID_BOOL, TRUE);
1912 db_get_value(hDB, 0, "/Experiment/Menu/Event Dump", &true_value, &size, TID_BOOL, TRUE);
1913 db_get_value(hDB, 0, "/Experiment/Menu/Config", &true_value, &size, TID_BOOL, TRUE);
1914 db_get_value(hDB, 0, "/Experiment/Menu/Example", &false_value, &size, TID_BOOL, TRUE);
1915 db_get_value(hDB, 0, "/Experiment/Menu/Help", &true_value, &size, TID_BOOL, TRUE);
1916
1917 //std::string buf;
1918 //status = db_get_value_string(hDB, 0, "/Experiment/Menu buttons", 0, &buf, FALSE);
1919 //if (status == DB_SUCCESS) {
1920 // cm_msg(MERROR, "init_menu_buttons", "ODB \"/Experiment/Menu buttons\" is obsolete, please delete it.");
1921 //}
1922
1923 check_obsolete_odb(hDB, "/Experiment/Menu buttons");
1924 check_obsolete_odb(hDB, "/Experiment/Menu/OldSequencer");
1925 check_obsolete_odb(hDB, "/Experiment/Menu/NewSequencer");
1926}
void check_obsolete_odb(HNDLE hDB, const char *odb_path)
Definition mhttpd.cxx:1881
Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_mhttpd_odb()

void init_mhttpd_odb ( MVOdb odb)

Definition at line 1930 of file mhttpd.cxx.

1931{
1932 HNDLE hDB;
1933 HNDLE hKey;
1934 int status;
1935 std::string s;
1937
1938 status = db_find_key(hDB, 0, "/Experiment/Base URL", &hKey);
1939 if (status == DB_SUCCESS) {
1940 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Base URL\" is obsolete, please delete it.");
1941 }
1942
1943 status = db_find_key(hDB, 0, "/Experiment/CSS File", &hKey);
1944 if (status == DB_SUCCESS) {
1945 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/CSS File\" is obsolete, please delete it.");
1946 }
1947
1948 status = db_find_key(hDB, 0, "/Experiment/JS File", &hKey);
1949 if (status == DB_SUCCESS) {
1950 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/JS File\" is obsolete, please delete it.");
1951 }
1952
1953 status = db_find_key(hDB, 0, "/Experiment/Start-Stop Buttons", &hKey);
1954 if (status == DB_SUCCESS) {
1955 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Start-Stop Buttons\" is obsolete, please delete it.");
1956 }
1957
1958 bool xdefault = true;
1959 odb->RB("Experiment/Pause-Resume Buttons", &xdefault, true);
1960
1961#ifdef HAVE_MONGOOSE616
1962 check_obsolete_odb(hDB, "/Experiment/midas http port");
1963 check_obsolete_odb(hDB, "/Experiment/midas https port");
1964 check_obsolete_odb(hDB, "/Experiment/http redirect to https");
1965 check_obsolete_odb(hDB, "/Experiment/Security/mhttpd hosts");
1966#endif
1967
1968 status = db_find_key(hDB, 0, "/Logger/Message file", &hKey);
1969 if (status == DB_SUCCESS) {
1970 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Logger/Message file\" is obsolete, please delete it and use \"/Logger/Message dir\" and \"/Logger/message file date format\" instead.");
1971 }
1972
1973 check_obsolete_odb(hDB, "/Logger/Watchdog timeout");
1974}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ interprete()

void interprete ( Param p,
Return r,
Attachment a,
const Cookies c,
const char dec_path,
RequestTrace t 
)

Definition at line 12254 of file mhttpd.cxx.

12262{
12263 int status;
12264 HNDLE hkey, hDB;
12265
12266 //printf("dec_path [%s]\n", dec_path);
12267
12268 if (strstr(dec_path, "favicon.ico") != 0 ||
12269 strstr(dec_path, "favicon.png")) {
12270 send_icon(r, dec_path);
12271 return;
12272 }
12273
12274 const char* password = p->getparam("pwd");
12275 const char* wpassword = p->getparam("wpwd");
12276 const char* command = p->getparam("cmd");
12277
12278 //printf("interprete: dec_path [%s], command [%s]\n", dec_path, command);
12279
12281 MVOdb* odb = gOdb;
12282
12283 if (history_mode) {
12284 if (equal_ustring(command, "history")) {
12285 if (equal_ustring(command, "config")) {
12286 return;
12287 }
12288
12289 Lock(t);
12290 show_hist_page(odb, p, r, dec_path, NULL, NULL, c->refresh);
12291 Unlock(t);
12292 return;
12293 }
12294 return;
12295 }
12296
12297 /* check for password */
12298 db_find_key(hDB, 0, "/Experiment/Security/Password", &hkey);
12299 if (!password[0] && hkey) {
12300 char str[256];
12301 int size = sizeof(str);
12302 db_get_data(hDB, hkey, str, &size, TID_STRING);
12303
12304 /* check for excemption */
12305 db_find_key(hDB, 0, "/Experiment/Security/Allowed programs/mhttpd", &hkey);
12306 if (hkey == 0 && strcmp(c->cookie_pwd.c_str(), str) != 0) {
12307 Lock(t);
12309 Unlock(t);
12310 return;
12311 }
12312 }
12313
12314 /*---- redirect with cookie if password given --------------------*/
12315
12316 if (password[0]) {
12317 r->rsprintf("HTTP/1.1 302 Found\r\n");
12318 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12319
12320 time_t now;
12321 time(&now);
12322
12323 now += 3600 * 24;
12324
12325 struct tm gmt_tms;
12326 gmtime_r(&now, &gmt_tms);
12327
12328 char str[256];
12329 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:00:00 GMT", &gmt_tms);
12330
12331 r->rsprintf("Set-Cookie: midas_pwd=%s; path=/; expires=%s\r\n",
12332 ss_crypt(password, "mi"), str);
12333
12334 r->rsprintf("Location: ./\n\n<html>redir</html>\r\n");
12335 return;
12336 }
12337
12338 if (wpassword[0]) {
12339 /* check if password correct */
12340 if (!check_web_password(r, hDB, dec_path, ss_crypt(wpassword, "mi"), p->getparam("redir")))
12341 return;
12342
12343 r->rsprintf("HTTP/1.1 302 Found\r\n");
12344 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12345
12346 time_t now;
12347 time(&now);
12348
12349 now += 3600 * 24;
12350
12351 struct tm gmt_tms;
12352 gmtime_r(&now, &gmt_tms);
12353
12354 char str[256];
12355 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:%M:%S GMT", &gmt_tms);
12356
12357 r->rsprintf("Set-Cookie: midas_wpwd=%s; path=/; expires=%s\r\n", ss_crypt(wpassword, "mi"), str);
12358
12359 sprintf(str, "./%s", p->getparam("redir"));
12360 r->rsprintf("Location: %s\n\n<html>redir</html>\r\n", str);
12361 return;
12362 }
12363
12364 /*---- send sound file -------------------------------------------*/
12365
12366 if (strlen(dec_path) > 3 &&
12367 dec_path[strlen(dec_path)-3] == 'm' &&
12368 dec_path[strlen(dec_path)-2] == 'p' &&
12369 dec_path[strlen(dec_path)-1] == '3') {
12370 if (strrchr(dec_path, '/'))
12371 send_resource(r, strrchr(dec_path, '/')+1);
12372 else
12374 return;
12375 }
12376
12377 /*---- send midas.js and midas.css -------------------------------*/
12378
12379 if (strstr(dec_path, "midas.js")) {
12380 send_resource(r, "midas.js");
12381 return;
12382 }
12383
12384 if (strstr(dec_path, "midas.css")) {
12385 send_resource(r, "midas.css");
12386 return;
12387 }
12388
12389 /*---- send mhttpd.js --------------------------------------------*/
12390
12391 if (strstr(dec_path, "mhttpd.js")) {
12392 send_resource(r, "mhttpd.js");
12393 return;
12394 }
12395
12396 /*---- send obsolete.js ------------------------------------------*/
12397
12398 if (strstr(dec_path, "obsolete.js")) {
12399 send_resource(r, "obsolete.js");
12400 return;
12401 }
12402
12403 /*---- send the obsolete mhttpd.css ------------------------------*/
12404
12405 if (strstr(dec_path, "mhttpd.css")) {
12406 send_resource(r, "mhttpd.css");
12407 return;
12408 }
12409
12410 /*---- send controls.js ------------------------------------------*/
12411
12412 if (strstr(dec_path, "controls.js")) {
12413 send_resource(r, "controls.js");
12414 return;
12415 }
12416
12417 /*---- send example web page -------------------------------------*/
12418
12419 if (equal_ustring(command, "example")) {
12420 send_resource(r, "example.html");
12421 return;
12422 }
12423
12424 /*---- send example custom page -------------------------------------*/
12425
12426 if (equal_ustring(command, "custom_example")) {
12427 send_resource(r, "custom_example.html");
12428 return;
12429 }
12430
12431 if (equal_ustring(command, "plot_example")) {
12432 send_resource(r, "plot_example.html");
12433 return;
12434 }
12435
12436 /*---- script command --------------------------------------------*/
12437
12438 if (p->getparam("script") && *p->getparam("script")) {
12439
12440 std::string str = msprintf("%s?script=%s", dec_path, p->getparam("script"));
12441 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12442 return;
12443
12444 std::string path;
12445 path += "/Script/";
12446 path += p->getparam("script");
12447
12448 Lock(t);
12449
12450 cm_exec_script(path.c_str());
12451
12452 Unlock(t);
12453
12454 if (p->isparam("redir"))
12455 redirect2(r, p->getparam("redir"));
12456 else
12457 redirect2(r, "");
12458
12459 return;
12460 }
12461
12462 /*---- customscript command --------------------------------------*/
12463
12464 if (p->getparam("customscript") && *p->getparam("customscript")) {
12465
12466 std::string str = msprintf("%s?customscript=%s", dec_path, p->getparam("customscript"));
12467 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12468 return;
12469
12470 std::string path;
12471 path += "/CustomScript/";
12472 path += p->getparam("customscript");
12473
12474 Lock(t);
12475
12476 cm_exec_script(path.c_str());
12477
12478 Unlock(t);
12479
12480 if (p->isparam("redir"))
12481 redirect2(r, p->getparam("redir"));
12482 else
12483 redirect2(r, str.c_str());
12484
12485 return;
12486 }
12487
12488 /*---- send the new html pages -----------------------------------*/
12489
12490 if (equal_ustring(command, "start")) {
12491 send_resource(r, "start.html");
12492 return;
12493 }
12494
12495 if ((equal_ustring(command, "") || equal_ustring(command, "status")) && strlen(dec_path) == 0) {
12496 if (midas::odb::exists("/Custom/Status")) {
12497 midas::odb custom("/Custom");
12498
12499 std::string filename = custom["Status"];
12500 filename = add_custom_path(filename);
12501
12502 // if custom file exists, send it (like normal web server)
12503 if (ss_file_exist(filename.c_str())) {
12504 send_file(r, filename);
12505 return;
12506 }
12507 } else
12508 send_resource(r, "status.html");
12509 return;
12510 }
12511
12512 if (equal_ustring(command, "eqtable")) {
12513 send_resource(r, "eqtable.html");
12514 return;
12515 }
12516
12517 if (equal_ustring(command, "newODB")) {
12518 send_resource(r, "odb.html");
12519 return;
12520 }
12521
12522 if (equal_ustring(command, "programs")) {
12523 send_resource(r, "programs.html");
12524 return;
12525 }
12526
12527 if (equal_ustring(command, "alarms")) {
12528 send_resource(r, "alarms.html");
12529 return;
12530 }
12531
12532 if (equal_ustring(command, "transition")) {
12533 send_resource(r, "transition.html");
12534 return;
12535 }
12536
12537 if (equal_ustring(command, "messages")) {
12538 send_resource(r, "messages.html");
12539 return;
12540 }
12541
12542 if (equal_ustring(command, "config") &&
12543 !(dec_path[0] == 'H' && dec_path[1] == 'S' && dec_path[2] == '/')) {
12544 send_resource(r, "config.html");
12545 return;
12546 }
12547
12548 if (equal_ustring(command, "chat")) {
12549 send_resource(r, "chat.html");
12550 return;
12551 }
12552
12553 if (equal_ustring(command, "buffers")) {
12554 send_resource(r, "buffers.html");
12555 return;
12556 }
12557
12558 if (equal_ustring(command, "Show elog")) {
12559 send_resource(r, "elog_show.html");
12560 return;
12561 }
12562
12563 if (equal_ustring(command, "Query elog")) {
12564 send_resource(r, "elog_query_form.html");
12565 return;
12566 }
12567
12568 if (equal_ustring(command, "New elog")) {
12569 send_resource(r, "elog_edit.html");
12570 return;
12571 }
12572
12573 if (equal_ustring(command, "Edit elog")) {
12574 send_resource(r, "elog_edit.html");
12575 return;
12576 }
12577
12578 if (equal_ustring(command, "Reply Elog")) {
12579 send_resource(r, "elog_edit.html");
12580 return;
12581 }
12582
12583 if (equal_ustring(command, "Last elog")) {
12584 send_resource(r, "elog_show.html");
12585 return;
12586 }
12587
12588 if (equal_ustring(command, "Submit Query")) {
12589 send_resource(r, "elog_query.html");
12590 return;
12591 }
12592
12593 if (equal_ustring(dec_path, "spinning-wheel.gif")) {
12594 send_resource(r, "spinning-wheel.gif");
12595 return;
12596 }
12597
12598 /*---- java script commands --------------------------------------*/
12599
12600 if (equal_ustring(command, "jset") ||
12601 equal_ustring(command, "jget") ||
12602 equal_ustring(command, "jcopy") ||
12603 equal_ustring(command, "jpaste") ||
12604 equal_ustring(command, "jkey") ||
12605 equal_ustring(command, "jcreate") ||
12606 equal_ustring(command, "jresize") ||
12607 equal_ustring(command, "jlink") ||
12608 equal_ustring(command, "jrename") ||
12609 equal_ustring(command, "jreorder") ||
12610 equal_ustring(command, "jdelete") ||
12611 equal_ustring(command, "jmsg") ||
12612 equal_ustring(command, "jalm") ||
12613 equal_ustring(command, "jgenmsg") ||
12614 equal_ustring(command, "jrpc_rev0") ||
12615 equal_ustring(command, "jrpc_rev1") ||
12616 equal_ustring(command, "jrpc")) {
12617 Lock(t);
12618 javascript_commands(p, r, c->cookie_cpwd.c_str());
12619 Unlock(t);
12620 return;
12621 }
12622
12623 /*---- history editord -------------------------------------------*/
12624
12625 if (equal_ustring(command, "hs_edit")) {
12626 send_resource(r, "hs_edit.html");
12627 return;
12628 }
12629
12630 /*---- history command -------------------------------------------*/
12631
12632 if (equal_ustring(command, "oldhistory")) {
12633 Lock(t);
12634 show_hist_page(odb, p, r, dec_path, NULL, NULL, c->refresh);
12635 Unlock(t);
12636 return;
12637 }
12638
12639 if (equal_ustring(command, "history")) {
12640 send_resource(r, "history.html");
12641 return;
12642 }
12643
12644 /*---- MSCB command ----------------------------------------------*/
12645
12646 if (equal_ustring(command, "MSCB")) {
12647 if (equal_ustring(command, "set")) {
12648 std::string str;
12649 str += dec_path;
12650 str += "?";
12651 str += add_param_to_url("cmd", command);
12652 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str.c_str()))
12653 return;
12654 }
12655
12656 Lock(t);
12657
12658#ifdef HAVE_MSCB
12659 show_mscb_page(p, r, c->refresh);
12660#else
12661 show_error(r, "MSCB support not compiled into this version of mhttpd");
12662#endif
12663
12664 Unlock(t);
12665 return;
12666 }
12667
12668 /*---- help command ----------------------------------------------*/
12669
12670 if (equal_ustring(command, "help")) {
12671 Lock(t);
12673 Unlock(t);
12674 return;
12675 }
12676
12677 /*---- trigger equipment readout ---------------------------*/
12678
12679 if (strncmp(command, "Trigger", 7) == 0) {
12680 std::string cmd;
12681 cmd += "?cmd=";
12682 cmd += command;
12683 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), cmd.c_str())) {
12684 return;
12685 }
12686
12687 Lock(t);
12688
12689 /* extract equipment name */
12690 char eq_name[NAME_LENGTH];
12691
12692 mstrlcpy(eq_name, command + 8, sizeof(eq_name));
12693 if (strchr(eq_name, ' '))
12694 *strchr(eq_name, ' ') = 0;
12695
12696 /* get frontend name */
12697 std::string path;
12698 path += "/Equipment/";
12699 path += eq_name;
12700 path += "/Common/Frontend name";
12701 char fe_name[NAME_LENGTH];
12702 int size = NAME_LENGTH;
12703 db_get_value(hDB, 0, path.c_str(), fe_name, &size, TID_STRING, TRUE);
12704
12705 /* and ID */
12706 path = "";
12707 path += "/Equipment/";
12708 path += eq_name;
12709 path += "/Common/Event ID";
12710 WORD event_id = 0;
12711 size = sizeof(event_id);
12712 db_get_value(hDB, 0, path.c_str(), &event_id, &size, TID_WORD, TRUE);
12713
12714 if (cm_exist(fe_name, FALSE) != CM_SUCCESS) {
12715 std::string str;
12716 str += "Frontend \"";
12717 str += fe_name;
12718 str += "\" not running!";
12719 show_error(r, str.c_str());
12720 } else {
12721 HNDLE hconn;
12723 if (status != RPC_SUCCESS) {
12724 std::string str;
12725 str += "Cannot connect to frontend \"";
12726 str += fe_name;
12727 str +="\" !";
12728 show_error(r, str.c_str());
12729 } else {
12731 if (status != CM_SUCCESS)
12732 show_error(r, "Error triggering event");
12733 else
12734 redirect(r, "");
12735
12736 //cm_disconnect_client(hconn, FALSE);
12737 }
12738 }
12739
12740 Unlock(t);
12741
12742 return;
12743 }
12744
12745 /*---- switch to next subrun -------------------------------------*/
12746
12747 if (strncmp(command, "Next Subrun", 11) == 0) {
12748 int i = TRUE;
12749 db_set_value(hDB, 0, "/Logger/Next subrun", &i, sizeof(i), 1, TID_BOOL);
12750 redirect(r, "");
12751 return;
12752 }
12753
12754 /*---- cancel command --------------------------------------------*/
12755
12756 if (equal_ustring(command, "cancel")) {
12757 if (p->isparam("redir"))
12758 redirect(r, p->getparam("redir"));
12759 else
12760 redirect(r, "");
12761 return;
12762 }
12763
12764 /*---- set command -----------------------------------------------*/
12765
12766 if (equal_ustring(command, "set")) {
12767 char str[256];
12768 mstrlcpy(str, "?cmd=set", sizeof(str));
12769 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), str))
12770 return;
12771
12772 const char* group = p->getparam("group");
12773 int index = atoi(p->getparam("index"));
12774 const char* value = p->getparam("value");
12775
12776 Lock(t);
12777 show_set_page(p, r, group, index, value);
12778 Unlock(t);
12779 return;
12780 }
12781
12782 /*---- find command ----------------------------------------------*/
12783
12784 if (equal_ustring(command, "find")) {
12785 const char* value = p->getparam("value");
12786 Lock(t);
12788 Unlock(t);
12789 return;
12790 }
12791
12792 /*---- CAMAC CNAF command ----------------------------------------*/
12793
12794 if (equal_ustring(command, "CNAF") || strncmp(dec_path, "CNAF", 4) == 0) {
12795 if (!check_web_password(r, hDB, dec_path, c->cookie_wpwd.c_str(), "?cmd=CNAF"))
12796 return;
12797
12798 Lock(t);
12799 show_cnaf_page(p, r);
12800 Unlock(t);
12801 return;
12802 }
12803
12804 /*---- ELog command ----------------------------------------------*/
12805
12806 if (equal_ustring(command, "elog")) {
12807 /* redirect to external ELOG if URL present */
12810 std::string external_elog_url;
12811 int size = sizeof(external_elog);
12812 status = db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
12813 status = db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
12814 if (external_elog && (external_elog_url.length() > 0)) {
12815 redirect(r, external_elog_url.c_str());
12816 return;
12817 }
12818 send_resource(r, "elog_show.html");
12819 return;
12820 }
12821
12822 // special processing for "Elog last 7d", etc
12823
12824 char cmdx[32];
12825 mstrlcpy(cmdx, command, sizeof(cmdx));
12826 cmdx[9] = 0;
12827
12828 if (equal_ustring(cmdx, "Elog last")) {
12829 // "Elog last 7d", etc
12830 send_resource(r, "elog_query.html");
12831 return;
12832 }
12833
12834 if (equal_ustring(command, "Create ELog from this page")) {
12835 std::string redir;
12836 redir += "?cmd=New+elog";
12837 redir += "&odb_path=";
12838 redir += p->getparam("odb_path");
12839 redirect(r, redir.c_str());
12840 return;
12841 }
12842
12843 if (equal_ustring(command, "Submit elog")) {
12844 Lock(t);
12845 submit_elog(odb, p, r, a);
12846 Unlock(t);
12847 return;
12848 }
12849
12850 if (equal_ustring(command, "elog_att")) {
12851 Lock(t);
12853 Unlock(t);
12854 return;
12855 }
12856
12857 /*---- accept command --------------------------------------------*/
12858
12859 if (equal_ustring(command, "accept")) {
12860 int refresh = atoi(p->getparam("refr"));
12861
12862 /* redirect with cookie */
12863 r->rsprintf("HTTP/1.1 302 Found\r\n");
12864 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12865 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
12866
12867 time_t now;
12868 time(&now);
12869
12870 now += 3600 * 24 * 365;
12871
12872 struct tm gmt_tms;
12873 gmtime_r(&now, &gmt_tms);
12874
12875 char str[256];
12876 strftime(str, sizeof(str), "%A, %d-%b-%Y %H:00:00 GMT", &gmt_tms);
12877
12878 r->rsprintf("Set-Cookie: midas_refr=%d; path=/; expires=%s\r\n", refresh, str);
12879 r->rsprintf("Location: ./\r\n\r\n<html>redir</html>\r\n");
12880
12881 return;
12882 }
12883
12884 /*---- slow control display --------------------------------------*/
12885
12886 if (equal_ustring(command, "eqtable")) {
12887 Lock(t);
12888 show_eqtable_page(p, r, c->refresh);
12889 Unlock(t);
12890 return;
12891 }
12892
12893 /*---- sequencer page --------------------------------------------*/
12894
12895 if (equal_ustring(command, "Sequencer")) {
12896 send_resource(r, "sequencer.html");
12897 return;
12898 }
12899
12900 // obsolete
12901 if (equal_ustring(command, "seq")) {
12902 send_resource(r, "sequencer.html");
12903 return;
12904 }
12905
12906 if (equal_ustring(command, "start_script")) {
12907 send_resource(r, "start_script.html");
12908 return;
12909 }
12910
12911 if (equal_ustring(command, "load_script")) {
12912 send_resource(r, "load_script.html");
12913 return;
12914 }
12915
12916 if (equal_ustring(command, "edit_script")) {
12917 send_resource(r, "edit_script.html");
12918 return;
12919 }
12920
12921 /*---- show ODB --------------------------------------------------*/
12922
12923 if (equal_ustring(command, "oldOdb")) {
12924 int write_access = TRUE;
12925 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
12926 if (hkey) {
12927 char str[256];
12928 int size = sizeof(str);
12929 db_get_data(hDB, hkey, str, &size, TID_STRING);
12930 if (strcmp(c->cookie_wpwd.c_str(), str) == 0)
12932 else
12934 }
12935
12936 std::string odb_path;
12937 if (p->getparam("odb_path") && *p->getparam("odb_path"))
12938 odb_path = p->getparam("odb_path");
12939
12940 Lock(t);
12941 show_odb_page(p, r, odb_path.c_str(), write_access);
12942 Unlock(t);
12943 return;
12944 }
12945
12946 /*---- New ODB browser --------------------------------------------*/
12947
12948 if (equal_ustring(command, "odb")) {
12949 send_resource(r, "odb.html");
12950 return;
12951 }
12952
12953 /*---- ODB show open records --------------------------------------*/
12954
12955 if (equal_ustring(command, "odb_sor")) {
12956 send_resource(r, "odb_sor.html");
12957 return;
12958 }
12959
12960 /*---- ODB show clients -------------------------------------------*/
12961
12962 if (equal_ustring(command, "odb_scl")) {
12963 send_resource(r, "odb_scl.html");
12964 return;
12965 }
12966
12967 /*---- old ODB path ----------------------------------------------*/
12968
12969 if ((command[0]==0) && dec_path[0]) {
12970 if (equal_ustring(dec_path, "root")) {
12971 std::string new_url = "./?cmd=odb";
12972 //printf("redirect old odb path url [%s] to [%s]\n", dec_path, new_url.c_str());
12973 redirect_307(r, new_url.c_str());
12974 return;
12975 }
12976 }
12977
12978 if ((command[0]==0) && dec_path[0]) {
12979 HNDLE hkey;
12981 //printf("try odb path [%s], status %d\n", dec_path, status);
12982 if (status == DB_SUCCESS) {
12983 int level = 0;
12984 for (const char* s = dec_path; *s; s++) {
12985 if (*s == '/')
12986 level++;
12987 }
12988 std::string new_url;
12989 if (level == 0) {
12990 // Top-level directory like /Logger, (which appears in dec_path as "Logger")
12991 new_url += "./";
12992 } else {
12993 for (int i=0; i<level; i++) {
12994 if (i>0)
12995 new_url += "/";
12996 new_url += "..";
12997 }
12998 }
12999 new_url += "?cmd=odb";
13000 new_url += "&odb_path=";
13002 //printf("redirect old odb path url [%s] to [%s]\n", dec_path, new_url.c_str());
13003 redirect_307(r, new_url.c_str());
13004 return;
13005 }
13006 }
13007
13008 /*---- event dump ------------------------------------------------*/
13009
13010 if (equal_ustring(command, "event dump")) {
13011 send_resource(r, "event_dump.html");
13012 return;
13013 }
13014
13015 /*---- custom page -----------------------------------------------*/
13016
13017 if (equal_ustring(command, "custom")) {
13018 Lock(t);
13019 show_custom_page(p, r, c->cookie_cpwd.c_str());
13020 Unlock(t);
13021 return;
13022 }
13023
13024 /*---- custom page accessed by direct URL that used to be under /CS/... ----*/
13025
13026 if (db_find_key(hDB, 0, "/Custom", &hkey) == DB_SUCCESS && dec_path[0]) {
13027 std::string odb_path;
13028 std::string value;
13029 int status;
13030
13031 odb_path = "";
13032 odb_path += "/Custom/Images/";
13033 odb_path += dec_path;
13034 odb_path += "/Background";
13035
13036 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13037
13038 //printf("Try custom gif [%s] status %d\n", odb_path.c_str(), status);
13039
13040 if (status == DB_SUCCESS) {
13041 if (strstr(dec_path, "..")) {
13042 std::string str;
13043 str += "Invalid custom gif name \'";
13044 str += dec_path;
13045 str += "\' contains \'..\'";
13046 show_error_404(r, str.c_str());
13047 return;
13048 }
13049
13050 Lock(t);
13052 Unlock(t);
13053 return;
13054 }
13055
13056 bool found_custom = false;
13057
13058 odb_path = "";
13059 odb_path += "/Custom/";
13060 odb_path += dec_path;
13061
13062 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13063
13064 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13065
13066 if (status == DB_SUCCESS) {
13067 found_custom = true;
13068 } else {
13069 odb_path = "";
13070 odb_path += "/Custom/";
13071 odb_path += dec_path;
13072 odb_path += "&";
13073
13074 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13075
13076 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13077
13078 if (status == DB_SUCCESS) {
13079 found_custom = true;
13080 } else {
13081 odb_path = "";
13082 odb_path += "/Custom/";
13083 odb_path += dec_path;
13084 odb_path += "!";
13085
13086 status = db_get_value_string(hDB, 0, odb_path.c_str(), 0, &value, FALSE);
13087
13088 //printf("Try [%s] status %d\n", odb_path.c_str(), status);
13089
13090 if (status == DB_SUCCESS) {
13091 found_custom = true;
13092 }
13093 }
13094 }
13095
13096 if (found_custom) {
13097 //printf("custom file: serving [%s] value [%s]\n", dec_path, value.c_str());
13098 if (strstr(dec_path, "..")) {
13099 std::string str;
13100 str += "Invalid custom page name \'";
13101 str += dec_path;
13102 str += "\' contains \'..\'";
13103 show_error_404(r, str.c_str());
13104 return;
13105 }
13106
13107 p->setparam("page", dec_path);
13108 Lock(t);
13109 show_custom_page(p, r, c->cookie_cpwd.c_str());
13110 Unlock(t);
13111 return;
13112 }
13113 }
13114
13115 /* new custom pages */
13116 if (db_find_key(hDB, 0, "/Custom", &hkey) == DB_SUCCESS && dec_path[0]) {
13117 std::string custom_path;
13118 status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
13119 if ((status == DB_SUCCESS) && (custom_path.length() > 0)) {
13120 if (strstr(dec_path, "..")) {
13121 std::string str;
13122 str += "Invalid custom file name \'";
13123 str += dec_path;
13124 str += "\' contains \'..\'";
13125 show_error_404(r, str.c_str());
13126 return;
13127 }
13128
13129 std::string full_filename = add_custom_path(dec_path);
13130
13131 // if custom file exists, send it (like normal web server)
13132 if (ss_file_exist(full_filename.c_str())) {
13134 return;
13135 }
13136 }
13137 }
13138
13139 /*---- redirect if web page --------------------------------------*/
13140
13141 //if (strlen(command) > 0) {
13142 // if (send_resource(r, std::string(command) + ".html", false))
13143 // return;
13144 //}
13145
13146 /*---- serve url as a resource file ------------------------------*/
13147
13148 if (strlen(p->getparam("path")) > 0) {
13149 if (send_resource(r, p->getparam("path"), false)) {
13150 return;
13151 }
13152 }
13153
13154 /*---- show status -----------------------------------------------*/
13155
13156 if (elog_mode) {
13157 redirect(r, "EL/");
13158 return;
13159 }
13160
13161 /* header */
13162 r->rsprintf("HTTP/1.1 400 Bad Request\r\n");
13163 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
13164 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
13165 r->rsprintf("\r\n");
13166 r->rsprintf("Error: Invalid URL \"%s\" or query \"%s\" or command \"%s\"\n", p->getparam("path"), p->getparam("query"), command);
13167}
void setparam(const char *param, const char *value)
Definition mhttpd.cxx:724
BOOL isparam(const char *param)
Definition mhttpd.cxx:803
static bool exists(const std::string &name)
Definition odbxx.cxx:66
int cm_exec_script(const char *odb_path_to_script)
Definition midas.cxx:5461
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7520
unsigned short int WORD
Definition mcstd.h:49
#define TID_WORD
Definition midas.h:332
int ss_file_exist(const char *path)
Definition system.cxx:7118
char * ss_crypt(const char *buf, const char *salt)
Definition system.cxx:7891
#define RPC_MANUAL_TRIG
Definition mrpc.h:128
static MVOdb * gOdb
Definition mhttpd.cxx:46
static BOOL history_mode
Definition mhttpd.cxx:93
void show_eqtable_page(Param *pp, Return *r, int refresh)
Definition mhttpd.cxx:2558
void show_find_page(Return *r, const char *value)
Definition mhttpd.cxx:7567
BOOL check_web_password(Return *r, HNDLE hDB, const char *dec_path, const char *password, const char *redir)
Definition mhttpd.cxx:6736
void submit_elog(MVOdb *odb, Param *pp, Return *r, Attachment *a)
Definition mhttpd.cxx:2248
static void urlEncode(char *ps, int ps_size)
Definition mhttpd.cxx:919
void redirect2(Return *r, const char *path)
Definition mhttpd.cxx:1444
static void show_cnaf_page(Param *p, Return *rr)
Definition mhttpd.cxx:5653
void javascript_commands(Param *p, Return *r, const char *cookie_cpwd)
Definition mhttpd.cxx:4443
void show_password_page(Return *r, const char *dec_path, const char *password)
Definition mhttpd.cxx:6702
bool send_resource(Return *r, const std::string &name, bool generate_404=true)
Definition mhttpd.cxx:1229
bool send_file(Return *r, const std::string &path, bool generate_404=true)
Definition mhttpd.cxx:1210
void show_elog_attachment(Param *p, Return *r, const char *path)
Definition mhttpd.cxx:2483
void Unlock(RequestTrace *t)
Definition mhttpd.cxx:12246
void redirect(Return *r, const char *path)
Definition mhttpd.cxx:1407
static std::string add_param_to_url(const char *name, const char *value)
Definition mhttpd.cxx:9780
std::string add_custom_path(const std::string &filename)
Definition mhttpd.cxx:3570
void show_odb_page(Param *pp, Return *r, const char *dec_path, int write_access)
Definition mhttpd.cxx:6793
void send_icon(Return *r, const char *icon)
Definition mhttpd.cxx:12188
static BOOL elog_mode
Definition mhttpd.cxx:92
void Lock(RequestTrace *t)
Definition mhttpd.cxx:12240
void show_set_page(Param *pp, Return *r, const char *group, int index, const char *value)
Definition mhttpd.cxx:7433
void show_hist_page(MVOdb *odb, Param *p, Return *r, const char *dec_path, char *buffer, int *buffer_size, int refresh)
Definition mhttpd.cxx:11262
void redirect_307(Return *r, const char *path)
Definition mhttpd.cxx:1431
void show_custom_page(Param *pp, Return *r, const char *cookie_cpwd)
Definition mhttpd.cxx:5419
void show_help_page(Return *r, const char *dec_path)
Definition mhttpd.cxx:1540
void show_error_404(Return *r, const char *error)
Definition mhttpd.cxx:1854
void show_custom_gif(Return *rr, const char *name)
Definition mhttpd.cxx:3672
#define event_id
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_editable()

BOOL is_editable ( char eq_name,
char var_name 
)

Definition at line 2531 of file mhttpd.cxx.

2532{
2533 HNDLE hDB, hkey;
2534 KEY key;
2535 char str[256];
2536 int i, size;
2537
2539 sprintf(str, "/Equipment/%s/Settings/Editable", eq_name);
2540 db_find_key(hDB, 0, str, &hkey);
2541
2542 /* if no editable entry found, use default */
2543 if (!hkey) {
2544 return (equal_ustring(var_name, "Demand") ||
2545 equal_ustring(var_name, "Output") || strncmp(var_name, "D_", 2) == 0);
2546 }
2547
2548 db_get_key(hDB, hkey, &key);
2549 for (i = 0; i < key.num_values; i++) {
2550 size = sizeof(str);
2553 return TRUE;
2554 }
2555 return FALSE;
2556}
char var_name[256]
Definition odbhist.cxx:41
Here is the call graph for this function:
Here is the caller graph for this function:

◆ javascript_commands()

void javascript_commands ( Param p,
Return r,
const char cookie_cpwd 
)

Definition at line 4443 of file mhttpd.cxx.

4444{
4445 int status;
4446 int size, i, n, index, type;
4447 unsigned int t;
4448 char str[TEXT_SIZE], format[256], facility[256], user[256];
4449 HNDLE hDB, hkey;
4450 KEY key;
4451 char data[TEXT_SIZE];
4452
4454
4455 // process common parameters
4456
4457 const int ENCODING_NONE = 0;
4458 const int ENCODING_ODB = 1;
4459 const int ENCODING_XML = 2;
4460 const int ENCODING_JSON = 3;
4461
4462 std::string cmd_parameter;
4463 std::string encoding_parameter;
4464 int encoding = ENCODING_NONE; // default encoding
4465 bool jsonp = false; // default is no JSONP wrapper
4466 std::string jsonp_callback; // default is no JSONP
4467 bool single = false; // single encoding
4468 bool multiple = false; // multiple encoding
4469 std::vector<std::string> odb; // multiple odb parameters
4470 //HNDLE hodb; // ODB handle for single odb parameter
4471 //std::vector<HNDLE> hodbm; // ODB handle for multiple odb parameter
4472
4473 if (p->isparam("cmd")) {
4474 cmd_parameter = p->getparam("cmd");
4475 }
4476
4477 if (p->isparam("encoding")) {
4478 encoding_parameter = p->getparam("encoding");
4479 }
4480
4481 if (encoding_parameter.length() > 0) {
4482 if (starts_with(encoding_parameter, "odb"))
4484 else if (starts_with(encoding_parameter, "xml"))
4486 else if (starts_with(encoding_parameter, "json"))
4488 }
4489
4490 if (encoding == ENCODING_JSON) {
4491 if (p->isparam("callback")) {
4492 jsonp = true;
4493 jsonp_callback = p->getparam("callback");
4494 }
4495 }
4496
4497 if (p->isparam("odb")) {
4498 single = true;
4499 odb.push_back(p->getparam("odb"));
4500 }
4501
4502 if (p->isparam("odb0")) {
4503 multiple = true;
4504 for (int i=0 ; ; i++) {
4505 char ppath[256];
4506 sprintf(ppath, "odb%d", i);
4507 if (!p->isparam(ppath))
4508 break;
4509 odb.push_back(p->getparam(ppath));
4510 }
4511 }
4512
4513 if (/* DISABLES CODE */ (0)) {
4514 printf("command [%s], encoding %d [%s], jsonp %d, single %d, multiple %d, odb array size %d\n", cmd_parameter.c_str(), encoding, encoding_parameter.c_str(), jsonp, single, multiple, (int)odb.size());
4515 }
4516
4517 /* process "jset" command */
4518 if (equal_ustring(p->getparam("cmd"), "jset")) {
4519
4520 if (*p->getparam("pnam")) {
4521 std::string ppath;
4522 ppath += "/Custom/Pwd/";
4523 ppath += p->getparam("pnam");
4524 str[0] = 0;
4525 db_get_value(hDB, 0, ppath.c_str(), str, &size, TID_STRING, TRUE);
4526 if (!equal_ustring(cookie_cpwd, str)) {
4528 r->rsprintf("Invalid password!");
4529 return;
4530 }
4531 }
4532 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4533 if (strchr(str, '[')) {
4534 if (*(strchr(str, '[')+1) == '*')
4535 index = -1;
4536 else
4537 index = atoi(strchr(str, '[')+1);
4538 *strchr(str, '[') = 0;
4539 } else
4540 index = 0;
4541
4542 if (db_find_key(hDB, 0, str, &hkey) == DB_SUCCESS && p->isparam("value")) {
4543 db_get_key(hDB, hkey, &key);
4544 memset(data, 0, sizeof(data));
4545 if (key.item_size <= (int)sizeof(data)) {
4546 if (index == -1) {
4547 const char* ptr = p->getparam("value");
4548 for (i=0 ; ptr != NULL ; i++) {
4549 size = sizeof(data);
4550 db_sscanf(ptr, data, &size, 0, key.type);
4551 if (strchr(data, ','))
4552 *strchr(data, ',') = 0;
4554 ptr = strchr(ptr, ',');
4555 if (ptr != NULL)
4556 ptr++;
4557 }
4558 } else {
4559 size = sizeof(data);
4560 db_sscanf(p->getparam("value"), data, &size, 0, key.type);
4561
4562 /* extend data size for single string if necessary */
4563 if ((key.type == TID_STRING || key.type == TID_LINK)
4564 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1) {
4565 key.item_size = strlen(data) + 1;
4567 } else
4569 }
4570 }
4571 } else {
4572 if (p->isparam("value") && p->isparam("type") && p->isparam("len")) {
4573 int type = atoi(p->getparam("type"));
4574 if (type == 0) {
4576 r->rsprintf("Invalid type %d!", type);
4577 return;
4578 }
4579 db_create_key(hDB, 0, str, type);
4580 db_find_key(hDB, 0, str, &hkey);
4581 if (!hkey) {
4583 r->rsprintf("Cannot create \'%s\' type %d", str, type);
4584 return;
4585 }
4586 db_get_key(hDB, hkey, &key);
4587 memset(data, 0, sizeof(data));
4588 size = sizeof(data);
4589 db_sscanf(p->getparam("value"), data, &size, 0, key.type);
4590 if (key.type == TID_STRING)
4591 db_set_data(hDB, hkey, data, atoi(p->getparam("len")), 1, TID_STRING);
4592 else {
4593 for (i=0 ; i<atoi(p->getparam("len")) ; i++)
4595 }
4596 }
4597 }
4598
4600 r->rsprintf("OK");
4601 return;
4602 }
4603
4604 /* process "jget" command */
4605 if (equal_ustring(p->getparam("cmd"), "jget")) {
4606
4607 if (p->isparam("odb")) {
4608 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4609 if (strchr(str, '[')) {
4610 if (*(strchr(str, '[')+1) == '*')
4611 index = -1;
4612 else
4613 index = atoi(strchr(str, '[')+1);
4614 *strchr(str, '[') = 0;
4615 } else
4616 index = 0;
4617
4619
4620 status = db_find_key(hDB, 0, str, &hkey);
4621
4622 if (status == DB_SUCCESS)
4623 output_key(p, r, hkey, index, p->getparam("format"));
4624 else
4625 r->rsputs("<DB_NO_KEY>");
4626 }
4627
4628 if (p->isparam("odb0")) {
4630 for (i=0 ; ; i++) {
4631 char ppath[256];
4632 sprintf(ppath, "odb%d", i);
4633 sprintf(format, "format%d", i);
4634 if (p->isparam(ppath)) {
4635 mstrlcpy(str, p->getparam(ppath), sizeof(str));
4636 if (strchr(str, '[')) {
4637 if (*(strchr(str, '[')+1) == '*')
4638 index = -1;
4639 else
4640 index = atoi(strchr(str, '[')+1);
4641 *strchr(str, '[') = 0;
4642 } else
4643 index = 0;
4644 if (i > 0)
4645 r->rsputs("$#----#$\n");
4646 if (db_find_key(hDB, 0, str, &hkey) == DB_SUCCESS)
4647 output_key(p, r, hkey, index, p->getparam(format));
4648 else
4649 r->rsputs("<DB_NO_KEY>");
4650
4651 } else
4652 break;
4653 }
4654 }
4655
4656 return;
4657 }
4658
4659 /* process "jcopy" command */
4660 if (equal_ustring(p->getparam("cmd"), "jcopy")) {
4661
4662 bool fmt_odb = false;
4663 bool fmt_xml = false;
4664 bool fmt_json = true;
4665 bool fmt_jsonp = false;
4666 int follow_links = 1;
4667 int save_keys = 1;
4668 int recurse = 1;
4669 const char* fmt = NULL;
4670 const char* jsonp_callback = "callback";
4671
4672 if (p->isparam("encoding")) {
4673 fmt = p->getparam("encoding");
4674 } else if (p->isparam("format")) {
4675 fmt = p->getparam("format");
4676 }
4677
4678 if (fmt) {
4679 fmt_odb = (equal_ustring(fmt, "odb") > 0);
4680 fmt_xml = (equal_ustring(fmt, "xml") > 0);
4681 fmt_json = (strstr(fmt, "json") != NULL);
4682
4683 if (fmt_odb)
4684 fmt_xml = fmt_json = false;
4685 if (fmt_xml)
4686 fmt_odb = fmt_json = false;
4687 if (fmt_json)
4688 fmt_odb = fmt_xml = false;
4689
4690 if (fmt_json)
4691 fmt_jsonp = (strstr(fmt, "-p") != NULL);
4692 if (fmt_jsonp && p->isparam("callback"))
4693 jsonp_callback = p->getparam("callback");
4694 if (fmt_json && strstr(fmt, "-nofollowlinks"))
4695 follow_links = 0;
4696 if (fmt_json && strstr(fmt, "-nokeys"))
4697 save_keys = 2;
4698 if (fmt_json && strstr(fmt, "-nolastwritten"))
4699 save_keys = 0;
4700 if (fmt_json && strstr(fmt, "-norecurse"))
4701 recurse = 0;
4702 }
4703
4704 if (p->isparam("odb")) {
4705 mstrlcpy(str, p->getparam("odb"), sizeof(str));
4706
4708
4709 if (fmt_json)
4710 status = db_find_link(hDB, 0, str, &hkey);
4711 else
4712 status = db_find_key(hDB, 0, str, &hkey);
4713 if (status == DB_SUCCESS) {
4714
4715 if (fmt_jsonp) {
4717 r->rsputs("(");
4718 }
4719
4720 int end = 0;
4722 char* buf = (char *)malloc(bufsize);
4723
4724 if (fmt_xml)
4725 db_copy_xml(hDB, hkey, buf, &bufsize, true);
4726 else if (fmt_json)
4728 else
4729 db_copy(hDB, hkey, buf, &bufsize, (char *)"");
4730
4731 r->rsputs(buf);
4732 free(buf);
4733
4734 if (fmt_jsonp) {
4735 r->rsputs(");\n");
4736 }
4737 } else
4738 r->rsputs("<DB_NO_KEY>");
4739 }
4740
4741 if (p->isparam("odb0")) {
4743 if (fmt_jsonp) {
4745 r->rsputs("(");
4746 }
4747 if (fmt_xml) {
4748 r->rsprintf("<?xml version=\"1.0\" encoding=\"%s\"?>\n", HTTP_ENCODING);
4749 r->rsputs("<jcopy>\n");
4750 r->rsputs("<data>\n");
4751 } else if (fmt_json)
4752 r->rsputs("[\n");
4753 else
4754 r->rsputs("");
4755 for (int i=0 ; ; i++) {
4756 char ppath[256];
4757 sprintf(ppath, "odb%d", i);
4758 if (!p->isparam(ppath))
4759 break;
4760 mstrlcpy(str, p->getparam(ppath), sizeof(str));
4761
4762 if (i > 0) {
4763 if (fmt_xml)
4764 r->rsputs("</data>\n<data>\n");
4765 else if (fmt_json)
4766 r->rsputs(",\n");
4767 else
4768 r->rsputs("$#----#$\n");
4769 }
4770
4771 if (fmt_json)
4772 status = db_find_link(hDB, 0, str, &hkey);
4773 else
4774 status = db_find_key(hDB, 0, str, &hkey);
4775 if (status != DB_SUCCESS) {
4776 if (fmt_xml)
4777 r->rsputs("<DB_NO_KEY/>\n");
4778 else if (fmt_json) {
4779 char tmp[256];
4780 sprintf(tmp, "{ \"/error\" : %d }\n", status);
4781 r->rsputs(tmp);
4782 } else
4783 r->rsputs("<DB_NO_KEY>\n");
4784 continue;
4785 }
4786
4787 int end = 0;
4789 char* buf = (char *)malloc(bufsize);
4790
4791 if (fmt_xml) {
4792 db_copy_xml(hDB, hkey, buf, &bufsize, true);
4793 const char* s = strstr(buf, "-->");
4794 if (s)
4795 s+=4;
4796 else
4797 s = buf;
4798 r->rsputs(s);
4799 } else if (fmt_json) {
4801 r->rsputs(buf);
4802 } else {
4803 db_copy(hDB, hkey, buf, &bufsize, (char *)"");
4804 r->rsputs(buf);
4805 }
4806
4807 free(buf);
4808 }
4809
4810 if (fmt_xml)
4811 r->rsputs("</data>\n</jcopy>\n");
4812 else if (fmt_json)
4813 r->rsputs("]\n");
4814 else
4815 r->rsputs("");
4816
4817 if (fmt_jsonp) {
4818 r->rsputs(");\n");
4819 }
4820 }
4821 return;
4822 }
4823
4824 /* process "jkey" command */
4825 if (equal_ustring(p->getparam("cmd"), "jkey")) {
4826
4827 // test:
4828 // curl "http://localhost:8080?cmd=jkey&odb0=/runinfo/run+number&odb1=/nonexistant&odb2=/&encoding=json&callback=aaa"
4829
4831
4832 if (jsonp) {
4833 r->rsputs(jsonp_callback.c_str());
4834 r->rsputs("(");
4835 }
4836
4837 if (multiple) {
4838 switch (encoding) {
4839 default:
4840 break;
4841 case ENCODING_JSON:
4842 r->rsprintf("[ ");
4843 break;
4844 }
4845 }
4846
4847 for (unsigned i=0; i<odb.size(); i++) {
4848 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
4849 if (status == DB_SUCCESS)
4851 switch (encoding) {
4852 default:
4853 if (multiple && i>0)
4854 r->rsputs("$#----#$\n");
4855 if (status == DB_SUCCESS) {
4856 r->rsprintf("%s\n", key.name);
4857 r->rsprintf("TID_%s\n", rpc_tid_name(key.type));
4858 r->rsprintf("%d\n", key.num_values);
4859 r->rsprintf("%d\n", key.item_size);
4860 r->rsprintf("%d\n", key.last_written);
4861 } else {
4862 r->rsputs("<DB_NO_KEY>\n");
4863 }
4864 break;
4865 case ENCODING_JSON:
4866 if (multiple && i>0)
4867 r->rsprintf(", ");
4868 if (status == DB_SUCCESS) {
4869 r->rsprintf("{ ");
4870 r->rsprintf("\"name\":\"%s\",", key.name);
4871 r->rsprintf("\"type\":%d,", key.type);
4872 r->rsprintf("\"type_name\":\"TID_%s\",", rpc_tid_name(key.type));
4873 r->rsprintf("\"num_values\":%d,", key.num_values);
4874 r->rsprintf("\"item_size\":%d,", key.item_size);
4875 r->rsprintf("\"last_written\":%d", key.last_written);
4876 r->rsprintf(" }");
4877 } else {
4878 r->rsprintf("{ \"/error\":%d }", status);
4879 }
4880 break;
4881 }
4882 }
4883
4884 if (multiple) {
4885 switch (encoding) {
4886 default:
4887 break;
4888 case ENCODING_JSON:
4889 r->rsprintf(" ]");
4890 break;
4891 }
4892 }
4893
4894 if (jsonp) {
4895 r->rsputs(");\n");
4896 }
4897
4898 return;
4899 }
4900
4901 /* process "jcreate" command */
4902 if (equal_ustring(p->getparam("cmd"), "jcreate")) {
4903
4904 // test:
4905 // curl "http://localhost:8080?cmd=jcreate&odb0=/test/foo&type0=7&odb1=/nonexistant&type1=100&odb2=/test/bar&type2=12&encoding=json&callback=aaa"
4906 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo&type=7"
4907 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo70&type=7&arraylen=10"
4908 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo12s&type=12&strlen=32"
4909 // curl "http://localhost:8080?cmd=jcreate&odb=/test/foo12s5&type=12&strlen=32&arraylen=5"
4910 // curl "http://localhost:8080?cmd=jcreate&odb0=/test/foo12s5x&type0=12&strlen0=32&arraylen0=5"
4911
4912
4914
4915 if (jsonp) {
4916 r->rsputs(jsonp_callback.c_str());
4917 r->rsputs("(");
4918 }
4919
4920 if (multiple) {
4921 switch (encoding) {
4922 default:
4923 case ENCODING_JSON:
4924 r->rsprintf("[ ");
4925 break;
4926 }
4927 }
4928
4929 for (unsigned i=0; i<odb.size(); i++) {
4930 HNDLE hkey = 0;
4931 int type = 0;
4932 int arraylength = 0;
4933 int strlength = 0;
4934
4935 if (single) {
4936 type = atoi(p->getparam("type"));
4937 arraylength = atoi(p->getparam("arraylen"));
4938 strlength = atoi(p->getparam("strlen"));
4939 }
4940 else if (multiple) {
4941 char buf[256];
4942 sprintf(buf, "type%d", i);
4943 type = atoi(p->getparam(buf));
4944 sprintf(buf, "arraylen%d", i);
4945 arraylength = atoi(p->getparam(buf));
4946 sprintf(buf, "strlen%d", i);
4947 strlength = atoi(p->getparam(buf));
4948 }
4949
4950 status = db_create_key(hDB, 0, odb[i].c_str(), type);
4951
4952 if (status == DB_SUCCESS) {
4953 status = db_find_link(hDB, 0, odb[i].c_str(), &hkey);
4954 }
4955
4956 if (status == DB_SUCCESS && hkey && type == TID_STRING && strlength > 0) {
4957 char* s = (char*)calloc(strlength, 1); // initialized to zero
4959 free(s);
4960 }
4961
4962 if (status == DB_SUCCESS && hkey && arraylength > 1) {
4964 }
4965
4966 switch (encoding) {
4967 default:
4968 case ENCODING_JSON:
4969 if (multiple && i>0)
4970 r->rsprintf(", ");
4971 r->rsprintf("%d", status);
4972 break;
4973 }
4974 }
4975
4976 if (multiple) {
4977 switch (encoding) {
4978 default:
4979 case ENCODING_JSON:
4980 r->rsprintf(" ]");
4981 break;
4982 }
4983 }
4984
4985 if (jsonp) {
4986 r->rsputs(");\n");
4987 }
4988
4989 return;
4990 }
4991
4992 /* process "jresize" command */
4993 if (equal_ustring(p->getparam("cmd"), "jresize")) {
4994
4995 // test:
4996
4997 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo70&arraylen=5"
4998 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&arraylen=5"
4999 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&strlen=16"
5000 // curl "http://localhost:8080?cmd=jresize&odb=/test/foo12s5&strlen=30&arraylen=10"
5001
5003
5004 if (jsonp) {
5005 r->rsputs(jsonp_callback.c_str());
5006 r->rsputs("(");
5007 }
5008
5009 if (multiple) {
5010 switch (encoding) {
5011 default:
5012 case ENCODING_JSON:
5013 r->rsprintf("[ ");
5014 break;
5015 }
5016 }
5017
5018 for (unsigned i=0; i<odb.size(); i++) {
5019 HNDLE hkey;
5020 KEY key;
5021 int arraylength = 0;
5022 int strlength = 0;
5023
5024 if (single) {
5025 arraylength = atoi(p->getparam("arraylen"));
5026 strlength = atoi(p->getparam("strlen"));
5027 }
5028 else if (multiple) {
5029 char buf[256];
5030 sprintf(buf, "arraylen%d", i);
5031 arraylength = atoi(p->getparam(buf));
5032 sprintf(buf, "strlen%d", i);
5033 strlength = atoi(p->getparam(buf));
5034 }
5035
5036 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5037
5038 if (status == DB_SUCCESS && hkey) {
5040 }
5041
5042 if (status == DB_SUCCESS && hkey && key.type == TID_STRING && strlength > 0) {
5044 char* olddata = (char*)malloc(oldsize);
5045 int size = oldsize;
5047
5048 if (status == DB_SUCCESS) {
5050 char* s = (char*)calloc(newsize, 1); // initialized to zero
5051 for (int k=0; k<key.num_values; k++) {
5053 }
5054
5056 free(s);
5057 }
5058
5059 free(olddata);
5060 }
5061
5062 if (status == DB_SUCCESS && hkey && arraylength > 0) {
5064 }
5065
5066 switch (encoding) {
5067 default:
5068 case ENCODING_JSON:
5069 if (multiple && i>0)
5070 r->rsprintf(", ");
5071 r->rsprintf("%d", status);
5072 break;
5073 }
5074 }
5075
5076 if (multiple) {
5077 switch (encoding) {
5078 default:
5079 case ENCODING_JSON:
5080 r->rsprintf(" ]");
5081 break;
5082 }
5083 }
5084
5085 if (jsonp) {
5086 r->rsputs(");\n");
5087 }
5088
5089 return;
5090 }
5091
5092 /* process "jrename" command */
5093 if (equal_ustring(p->getparam("cmd"), "jrename")) {
5094
5095 // test:
5096 // curl "http://localhost:8080?cmd=jrename&odb0=/test/foo&type0=7&odb1=/nonexistant&type1=100&odb2=/test/bar&type2=12&encoding=json&callback=aaa"
5097 // curl "http://localhost:8080?cmd=jrename&odb=/test/foo&name=foofoo"
5098
5100
5101 if (jsonp) {
5102 r->rsputs(jsonp_callback.c_str());
5103 r->rsputs("(");
5104 }
5105
5106 if (multiple) {
5107 switch (encoding) {
5108 default:
5109 case ENCODING_JSON:
5110 r->rsprintf("[ ");
5111 break;
5112 }
5113 }
5114
5115 for (unsigned i=0; i<odb.size(); i++) {
5116 const char* name = NULL;
5117 if (single)
5118 name = p->getparam("name");
5119 else if (multiple) {
5120 char buf[256];
5121 sprintf(buf, "name%d", i);
5122 name = p->getparam(buf);
5123 }
5124 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5125 if (status == DB_SUCCESS) {
5127 }
5128 switch (encoding) {
5129 default:
5130 case ENCODING_JSON:
5131 if (multiple && i>0)
5132 r->rsprintf(", ");
5133 r->rsprintf("%d", status);
5134 break;
5135 }
5136 }
5137
5138 if (multiple) {
5139 switch (encoding) {
5140 default:
5141 case ENCODING_JSON:
5142 r->rsprintf(" ]");
5143 break;
5144 }
5145 }
5146
5147 if (jsonp) {
5148 r->rsputs(");\n");
5149 }
5150
5151 return;
5152 }
5153
5154 /* process "jlink" command */
5155 if (equal_ustring(p->getparam("cmd"), "jlink")) {
5156
5157 // test:
5158 // curl "http://localhost:8080?cmd=jlink&odb=/test/link&dest=/test/foo"
5159 // curl "http://localhost:8080?cmd=jlink&odb0=/test/link0&dest0=/test/foo&odb1=/test/link1&dest1=/test/foo"
5160
5162
5163 if (jsonp) {
5164 r->rsputs(jsonp_callback.c_str());
5165 r->rsputs("(");
5166 }
5167
5168 if (multiple) {
5169 switch (encoding) {
5170 default:
5171 case ENCODING_JSON:
5172 r->rsprintf("[ ");
5173 break;
5174 }
5175 }
5176
5177 for (unsigned i=0; i<odb.size(); i++) {
5178 const char* dest = NULL;
5179 if (single)
5180 dest = p->getparam("dest");
5181 else if (multiple) {
5182 char buf[256];
5183 sprintf(buf, "dest%d", i);
5184 dest = p->getparam(buf);
5185 }
5186
5187 status = db_create_link(hDB, 0, odb[i].c_str(), dest);
5188
5189 switch (encoding) {
5190 default:
5191 case ENCODING_JSON:
5192 if (multiple && i>0)
5193 r->rsprintf(", ");
5194 r->rsprintf("%d", status);
5195 break;
5196 }
5197 }
5198
5199 if (multiple) {
5200 switch (encoding) {
5201 default:
5202 case ENCODING_JSON:
5203 r->rsprintf(" ]");
5204 break;
5205 }
5206 }
5207
5208 if (jsonp) {
5209 r->rsputs(");\n");
5210 }
5211
5212 return;
5213 }
5214
5215 /* process "jreorder" command */
5216 if (equal_ustring(p->getparam("cmd"), "jreorder")) {
5217
5218 // test:
5219 // curl "http://localhost:8080?cmd=jreorder&odb0=/test/foo&index0=0&odb1=/test/bar&index1=1"
5220 // curl "http://localhost:8080?cmd=jreorder&odb=/test/bar&index=0"
5221
5223
5224 if (jsonp) {
5225 r->rsputs(jsonp_callback.c_str());
5226 r->rsputs("(");
5227 }
5228
5229 if (multiple) {
5230 switch (encoding) {
5231 default:
5232 case ENCODING_JSON:
5233 r->rsprintf("[ ");
5234 break;
5235 }
5236 }
5237
5238 for (unsigned i=0; i<odb.size(); i++) {
5239 int index = 0;
5240 if (single)
5241 index = atoi(p->getparam("index"));
5242 else if (multiple) {
5243 char buf[256];
5244 sprintf(buf, "index%d", i);
5245 index = atoi(p->getparam(buf));
5246 }
5247
5248 status = db_find_key(hDB, 0, odb[i].c_str(), &hkey);
5249 if (status == DB_SUCCESS) {
5251 }
5252
5253 switch (encoding) {
5254 default:
5255 case ENCODING_JSON:
5256 if (multiple && i>0)
5257 r->rsprintf(", ");
5258 r->rsprintf("%d", status);
5259 break;
5260 }
5261 }
5262
5263 if (multiple) {
5264 switch (encoding) {
5265 default:
5266 case ENCODING_JSON:
5267 r->rsprintf(" ]");
5268 break;
5269 }
5270 }
5271
5272 if (jsonp) {
5273 r->rsputs(");\n");
5274 }
5275
5276 return;
5277 }
5278
5279 /* process "jdelete" command */
5280 if (equal_ustring(p->getparam("cmd"), "jdelete")) {
5281
5282 // test:
5283 // curl "http://localhost:8080?cmd=jdelete&odb0=/test/foo&odb1=/nonexistant&odb2=/test/bar&encoding=json&callback=aaa"
5284 // curl "http://localhost:8080?cmd=jdelete&odb=/test/foo"
5285
5287
5288 if (jsonp) {
5289 r->rsputs(jsonp_callback.c_str());
5290 r->rsputs("(");
5291 }
5292
5293 if (multiple) {
5294 switch (encoding) {
5295 default:
5296 case ENCODING_JSON:
5297 r->rsprintf("[ ");
5298 break;
5299 }
5300 }
5301
5302 for (unsigned i=0; i<odb.size(); i++) {
5303 BOOL follow_links = 0;
5304 status = db_find_link(hDB, 0, odb[i].c_str(), &hkey);
5305 if (status == DB_SUCCESS) {
5307 }
5308 switch (encoding) {
5309 default:
5310 case ENCODING_JSON:
5311 if (multiple && i>0)
5312 r->rsprintf(", ");
5313 r->rsprintf("%d", status);
5314 break;
5315 }
5316 }
5317
5318 if (multiple) {
5319 switch (encoding) {
5320 default:
5321 case ENCODING_JSON:
5322 r->rsprintf(" ]");
5323 break;
5324 }
5325 }
5326
5327 if (jsonp) {
5328 r->rsputs(");\n");
5329 }
5330
5331 return;
5332 }
5333
5334 /* process "jmsg" command */
5335 if (equal_ustring(p->getparam("cmd"), "jmsg")) {
5336
5337 if (p->getparam("f") && *p->getparam("f"))
5338 mstrlcpy(facility, p->getparam("f"), sizeof(facility));
5339 else
5340 mstrlcpy(facility, "midas", sizeof(facility));
5341
5342 n = 1;
5343 if (p->getparam("n") && *p->getparam("n"))
5344 n = atoi(p->getparam("n"));
5345
5346 t = 0;
5347 if (p->getparam("t") && p->getparam("t"))
5348 t = atoi(p->getparam("t"));
5349
5351 char* messages = NULL;
5352 int num_messages = 0;
5354 if (messages) {
5355 r->rsputs(messages);
5356 free(messages);
5357 }
5358 return;
5359 }
5360
5361 /* process "jgenmsg" command */
5362 if (equal_ustring(p->getparam("cmd"), "jgenmsg")) {
5363
5364 if (p->getparam("facility") && *p->getparam("facility"))
5365 mstrlcpy(facility, p->getparam("facility"), sizeof(facility));
5366 else
5367 mstrlcpy(facility, "midas", sizeof(facility));
5368
5369 if (p->getparam("user") && *p->getparam("user"))
5370 mstrlcpy(user, p->getparam("user"), sizeof(user));
5371 else
5372 mstrlcpy(user, "javascript_commands", sizeof(user));
5373
5374 if (p->getparam("type") && *p->getparam("type"))
5375 type = atoi(p->getparam("type"));
5376 else
5377 type = MT_INFO;
5378
5379 if (p->getparam("msg") && *p->getparam("msg")) {
5380 cm_msg1(type, __FILE__, __LINE__, facility, user, "%s", p->getparam("msg"));
5381 }
5382
5384 r->rsputs("Message successfully created\n");
5385 return;
5386 }
5387
5388 /* process "jalm" command */
5389 if (equal_ustring(p->getparam("cmd"), "jalm")) {
5390
5392 std::string alarms;
5394 r->rsputs(alarms.c_str());
5395 return;
5396 }
5397
5398 /* process "jrpc" command */
5399 if (equal_ustring(p->getparam("cmd"), "jrpc_rev0")) {
5400 do_jrpc_rev0(p, r);
5401 return;
5402 }
5403
5404 /* process "jrpc" command */
5405 if (equal_ustring(p->getparam("cmd"), "jrpc_rev1")) {
5406 do_jrpc_rev1(p, r);
5407 return;
5408 }
5409
5410 /* process "jrpc" command */
5411 if (equal_ustring(p->getparam("cmd"), "jrpc")) {
5412 do_jrpc(p, r);
5413 return;
5414 }
5415}
INT al_get_alarms(std::string *presult)
Definition alarm.cxx:844
#define MT_INFO
Definition midas.h:543
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:973
INT cm_msg_retrieve2(const char *facility, time_t t, INT n_message, char **messages, int *num_messages)
Definition midas.cxx:1264
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4274
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6361
INT db_copy(HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, const char *path)
Definition odb.cxx:8217
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3308
INT db_copy_xml(HNDLE hDB, HNDLE hKey, char *buffer, int *buffer_size, bool header)
Definition odb.cxx:9037
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7648
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7215
INT db_copy_json_obsolete(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int save_keys, int follow_links, int recurse)
Definition odb.cxx:10508
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6261
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
Definition odb.cxx:11314
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7502
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:3601
const char * rpc_tid_name(INT id)
Definition midas.cxx:11764
INT rpc_tid_size(INT id)
Definition midas.cxx:11757
#define WEB_BUFFER_SIZE
Definition mhttpd.cxx:509
void output_key(Param *p, Return *r, HNDLE hkey, int index, const char *format)
Definition mhttpd.cxx:4368
void do_jrpc(Param *p, Return *r)
Definition mhttpd.cxx:4318
void do_jrpc_rev1(Param *p, Return *r)
Definition mhttpd.cxx:4139
void do_jrpc_rev0(Param *p, Return *r)
Definition mhttpd.cxx:4014
#define TEXT_SIZE
Definition mhttpd.cxx:697
#define end
INT last_written
Definition midas.h:1037
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadHistPlotFromOdb()

static void LoadHistPlotFromOdb ( MVOdb odb,
HistPlot hp,
const char group,
const char panel 
)
static

Definition at line 10195 of file mhttpd.cxx.

10196{
10197 std::string path = "History/Display/";
10198 path += group;
10199 path += "/";
10200 path += panel;
10201
10202 MVOdb* o = odb->Chdir(path.c_str());
10203 if (!o) {
10204 return;
10205 }
10206
10207 o->RS("Timescale", &hp->timescale);
10208 o->RD("Minimum", &hp->minimum);
10209 o->RD("Maximum", &hp->maximum);
10210 o->RB("Zero ylow", &hp->zero_ylow);
10211 o->RB("Log axis", &hp->log_axis);
10212 o->RB("Zero ylow", &hp->zero_ylow);
10213 o->RB("Show run markers", &hp->show_run_markers);
10214 o->RB("Show values", &hp->show_values);
10215 o->RB("Show fill", &hp->show_fill);
10216 o->RB("Show factor", &hp->show_factor);
10217 //o->RB("Enable factor and offset", &hp->enable_factor);
10218
10219 std::vector<std::string> hist_vars;
10220 std::vector<std::string> hist_formula;
10221 std::vector<std::string> hist_colour;
10222 std::vector<std::string> hist_label;
10223 std::vector<bool> hist_show_raw_value;
10224 std::vector<double> hist_factor;
10225 std::vector<double> hist_offset;
10226 std::vector<double> hist_voffset;
10227
10228 o->RSA("Variables", &hist_vars);
10229 o->RSA("Formula", &hist_formula);
10230 o->RSA("Colour", &hist_colour);
10231 o->RSA("Label", &hist_label);
10232 o->RBA("Show raw value", &hist_show_raw_value);
10233 o->RDA("Factor", &hist_factor);
10234 o->RDA("Offset", &hist_offset);
10235 o->RDA("VOffset", &hist_voffset);
10236
10237 // fix broken plots with "factor" all zero. for reasons
10238 // unknown the new history code has corrupted many
10239 // history plot definitions like this. K.O.
10240 {
10241 bool all_zero = true;
10242 for (size_t i=0; i<hist_factor.size(); i++) {
10243 if (hist_factor[i] != 0)
10244 all_zero = false;
10245 }
10246 if (all_zero) {
10247 for (size_t i=0; i<hist_factor.size(); i++) {
10248 hist_factor[i] = 1.0;
10249 }
10250 }
10251 }
10252
10253 size_t num = std::max(hist_vars.size(), hist_formula.size());
10254 num = std::max(num, hist_colour.size());
10255 num = std::max(num, hist_label.size());
10256 num = std::max(num, hist_show_raw_value.size());
10257 num = std::max(num, hist_factor.size());
10258 num = std::max(num, hist_offset.size());
10259 num = std::max(num, hist_voffset.size());
10260
10261 hist_vars.resize(num);
10262 hist_formula.resize(num);
10263 hist_colour.resize(num);
10264 hist_label.resize(num);
10265 hist_show_raw_value.resize(num);
10266 hist_factor.resize(num, 1.0);
10267 hist_offset.resize(num, 0.0);
10268 hist_voffset.resize(num, 0.0);
10269
10270 for (size_t i=0; i<num; i++) {
10271 HistVar v;
10272
10274
10275 v.formula = hist_formula[i];
10276 v.colour = hist_colour[i];
10277 v.label = hist_label[i];
10279 v.factor = hist_factor[i];
10280 v.offset = hist_offset[i];
10281 v.voffset = hist_voffset[i];
10283
10284 // one-time migration of factor and offset to formula
10285 if (hp->enable_factor && v.formula.empty()) {
10286 if (v.factor!=1 || v.offset!=0 || v.voffset!=0) {
10287 v.formula = msprintf("%g%+g*(x%+g)", v.offset, v.factor, -v.voffset);
10288 }
10289 }
10290
10291 hp->vars.push_back(v);
10292 }
10293
10294// printf("Load from ODB %s: ", path.c_str());
10295// PrintHistPlot(*hp);
10296
10297 delete o;
10298}
double factor
Definition mhttpd.cxx:8333
double offset
Definition mhttpd.cxx:8334
std::string formula
Definition mhttpd.cxx:8328
std::string label
Definition mhttpd.cxx:8330
double voffset
Definition mhttpd.cxx:8335
bool show_raw_value
Definition mhttpd.cxx:8331
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadHistPlotFromParam()

static void LoadHistPlotFromParam ( HistPlot hp,
Param p 
)
static

Definition at line 10300 of file mhttpd.cxx.

10301{
10302 hp->timescale = p->getparam("timescale");
10303 hp->minimum = strtod(p->getparam("minimum"), NULL);
10304 hp->maximum = strtod(p->getparam("maximum"), NULL);
10305 hp->zero_ylow = *p->getparam("zero_ylow");
10306 hp->log_axis = *p->getparam("log_axis");
10307 hp->show_run_markers = *p->getparam("run_markers");
10308 hp->show_values = *p->getparam("show_values");
10309 hp->show_fill = *p->getparam("show_fill");
10310 hp->show_factor = *p->getparam("show_factor");
10311 //hp->enable_factor = *p->getparam("enable_factor");
10312
10313 for (int index=0; ; index++) {
10314 char str[256];
10315 sprintf(str, "event%d", index);
10316
10317 //printf("param event %d: [%s] [%s] [%d]\n", index, str, p->getparam(str), *p->getparam(str));
10318
10319 if (!p->isparam(str))
10320 break;
10321
10322 if (*p->getparam(str) == '/') // "/empty"
10323 continue;
10324
10325 HistVar v;
10326
10327 v.event_name = p->xgetparam(str);
10328
10329 sprintf(str, "var%d", index);
10330 v.tag_name = p->xgetparam(str);
10331
10332 sprintf(str, "form%d", index);
10333 v.formula = p->xgetparam(str);
10334
10335 sprintf(str, "col%d", index);
10336 v.colour = p->xgetparam(str);
10337
10338 sprintf(str, "lab%d", index);
10339 v.label = p->xgetparam(str);
10340
10341 sprintf(str, "raw%d", index);
10342 v.show_raw_value = atoi(p->xgetparam(str).c_str());
10343
10344 sprintf(str, "factor%d", index);
10345 if (p->isparam(str)) {
10346 v.factor = atof(p->xgetparam(str).c_str());
10347 } else {
10348 v.factor = 1.0;
10349 }
10350
10351 sprintf(str, "offset%d", index);
10352 v.offset = atof(p->xgetparam(str).c_str());
10353
10354 sprintf(str, "voffset%d", index);
10355 v.voffset = atof(p->xgetparam(str).c_str());
10356
10357 sprintf(str, "ord%d", index);
10358 if (p->isparam(str)) {
10359 v.order = atoi(p->xgetparam(str).c_str());
10360 } else {
10362 }
10363
10364 hp->vars.push_back(v);
10365 }
10366
10367 /* correctly number newly added variables */
10368 for (size_t index=0; index<hp->vars.size(); index++) {
10369 if (hp->vars[index].order < 0)
10370 hp->vars[index].order = NextHistPlotOrder(*hp);
10371 }
10372
10373// printf("Load from param:\n");
10374// PrintHistPlot(*hp);
10375}
std::string xgetparam(const char *param)
Definition mhttpd.cxx:794
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Lock()

void Lock ( RequestTrace t)

Definition at line 12240 of file mhttpd.cxx.

12241{
12242 gMutex.lock();
12243 t->fTimeLocked = GetTimeSec();
12244}
double fTimeLocked
Definition mhttpd.cxx:387
static std::mutex gMutex
Definition mhttpd.cxx:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
const char argv[] 
)

Definition at line 16210 of file mhttpd.cxx.

16211{
16212 int status;
16213 int daemon = FALSE;
16214#ifdef HAVE_MONGOOSE6
16215 int user_http_port = 0;
16216 int user_https_port = 0;
16217#endif
16218#ifdef HAVE_MONGOOSE616
16219 bool no_passwords = false;
16220 bool no_hostlist = false;
16221#endif
16222 const char *myname = "mhttpd";
16223
16224 setbuf(stdout, NULL);
16225 setbuf(stderr, NULL);
16226#ifdef SIGPIPE
16227 /* avoid getting killed by "Broken pipe" signals */
16229#endif
16230
16231#ifdef HAVE_MONGOOSE6
16232 //
16233 // if running setuid-root, unconditionally bind to port 80.
16234 //
16235
16236 int socket_priviledged_port = -1;
16237
16238#ifdef OS_UNIX
16239 // in setuid-root mode bind to priviledged port
16240 if (getuid() != geteuid()) {
16241 int port80 = 80;
16242
16243 printf("mhttpd is running in setuid-root mode.\n");
16244
16246 if (socket_priviledged_port < 0) {
16247 printf("Cannot open listening socket on TCP port %d, aborting.\n", port80);
16248 exit(1);
16249 }
16250
16251 // give up root privilege
16252 status = setuid(getuid());
16253 if (status != 0) {
16254 printf("Cannot give up root privelege, aborting.\n");
16255 exit(1);
16256 }
16257 status = setuid(getuid());
16258 if (status != 0) {
16259 printf("Cannot give up root privelege, aborting.\n");
16260 exit(1);
16261 }
16262 }
16263#endif
16264#endif
16265
16266 char midas_hostname[256];
16267 char midas_expt[256];
16268
16269 /* get default from environment */
16271
16272 /* parse command line parameters */
16273#ifdef HAVE_MONGOOSE6
16274 gUserAllowedHosts.clear();
16275#else
16276 std::vector<std::string> user_hostlist;
16277#endif
16278 for (int i = 1; i < argc; i++) {
16279 if (argv[i][0] == '-' && argv[i][1] == 'D')
16280 daemon = TRUE;
16281 else if (argv[i][0] == '-' && argv[i][1] == 'v')
16282 verbose = TRUE;
16283 else if (argv[i][0] == '-' && argv[i][1] == 'E')
16284 elog_mode = TRUE;
16285 else if (argv[i][0] == '-' && argv[i][1] == 'H') {
16287#ifdef HAVE_MONGOOSE6
16288 } else if (strcmp(argv[i], "--http") == 0) {
16289 if (argv[i+1]) {
16290 user_http_port = atoi(argv[i+1]);
16291 }
16292 } else if (strcmp(argv[i], "--https") == 0) {
16293 if (argv[i+1]) {
16294 user_https_port = atoi(argv[i+1]);
16295 }
16296#endif
16297 } else if (strcmp(argv[i], "--trace-mg") == 0) {
16298 trace_mg = true;
16299 trace_mg_recv = true;
16300 trace_mg_send = true;
16301 } else if (strcmp(argv[i], "--no-trace-mg-recv") == 0) {
16302 trace_mg_recv = false;
16303 } else if (strcmp(argv[i], "--no-trace-mg-send") == 0) {
16304 trace_mg_send = false;
16305 } else if (strcmp(argv[i], "--verbose-mg") == 0) {
16306 verbose_mg = true;
16307#ifdef HAVE_MONGOOSE616
16308 } else if (strcmp(argv[i], "--no-multithread") == 0) {
16309 multithread_mg = false;
16310 } else if (strcmp(argv[i], "--no-passwords") == 0) {
16311 no_passwords = true;
16312 } else if (strcmp(argv[i], "--no-hostlist") == 0) {
16313 no_hostlist = true;
16314#endif
16315 } else if (argv[i][0] == '-') {
16316 if (i + 1 >= argc || argv[i + 1][0] == '-')
16317 goto usage;
16318 if (argv[i][1] == 'h')
16320 else if (argv[i][1] == 'e')
16321 mstrlcpy(midas_expt, argv[++i], sizeof(midas_hostname));
16322 else if (argv[i][1] == 'a') {
16323#ifdef HAVE_MONGOOSE6
16324 gUserAllowedHosts.push_back(argv[++i]);
16325#else
16326 user_hostlist.push_back(argv[++i]);
16327#endif
16328 } else if (argv[i][1] == 'p') {
16329 printf("Option \"-p port_number\" for the old web server is obsolete.\n");
16330 printf("mongoose web server is the new default, port number is set in ODB or with \"--http port_number\".\n");
16331 printf("To run the obsolete old web server, please use \"--oldserver\" switch.\n");
16332 return 1;
16333 } else {
16334 usage:
16335 printf("usage: %s [-h Hostname[:port]] [-e Experiment] [-v] [-D] [-a Hostname]\n\n", argv[0]);
16336 printf(" -a add hostname to the hostlist of hosts allowed to connect to mhttpd\n");
16337 printf(" -e experiment to connect to\n");
16338 printf(" -h connect to midas server (mserver) on given host\n");
16339 printf(" -v display verbose HTTP communication\n");
16340 printf(" -D become a daemon\n");
16341 printf(" -E only display ELog system\n");
16342 printf(" -H only display history plots\n");
16343#ifdef HAVE_MONGOOSE6
16344 printf(" --http port - bind to specified HTTP port (default is ODB \"/Experiment/midas http port\")\n");
16345 printf(" --https port - bind to specified HTTP port (default is ODB \"/Experiment/midas https port\")\n");
16346#endif
16347 printf(" --verbose-mg - trace mongoose web requests\n");
16348 printf(" --trace-mg - trace mongoose events\n");
16349 printf(" --no-trace-mg-recv - do not trace mongoose recv events\n");
16350 printf(" --no-trace-mg-send - dop not trace mongoose send events\n");
16351#ifdef HAVE_MONGOOSE616
16352 printf(" --no-multithread - disable mongoose multithreading\n");
16353 printf(" --no-passwords - disable password protection\n");
16354 printf(" --no-hostlist - disable access control host list\n");
16355#endif
16356 return 0;
16357 }
16358 }
16359 }
16360
16361 if (daemon) {
16362 printf("Becoming a daemon...\n");
16364 }
16365
16366#ifdef OS_LINUX
16367 /* write PID file */
16368 FILE *f = fopen("/var/run/mhttpd.pid", "w");
16369 if (f != NULL) {
16370 fprintf(f, "%d", ss_getpid());
16371 fclose(f);
16372 }
16373#endif
16374
16375 if (history_mode)
16376 myname = "mhttpd_history";
16377
16378 /*---- connect to experiment ----*/
16382 return 1;
16383 else if (status == DB_INVALID_HANDLE) {
16384 std::string s = cm_get_error(status);
16385 puts(s.c_str());
16386 } else if (status != CM_SUCCESS) {
16387 std::string s = cm_get_error(status);
16388 puts(s.c_str());
16389 return 1;
16390 }
16391
16392 /* mhttpd needs the watchdog thread until we are sure
16393 * we do not have any long sleeps anywhere in the mhttpd code.
16394 * this includes reads from the history files or databases,
16395 * that can take arbitrary long time */
16397
16398 /* Get ODB handles */
16399
16400 HNDLE hDB;
16401
16403
16404 MVOdb *odb = MakeMidasOdb(hDB);
16405 gOdb = odb;
16406
16407 /* do ODB record checking */
16408 if (!check_odb_records(odb)) {
16409 // check_odb_records() fails with nothing printed to the terminal
16410 // because mhttpd does not print cm_msg(MERROR, ...) messages to the terminal.
16411 // At least print something!
16412 printf("check_odb_records() failed, see messages and midas.log, bye!\n");
16414 return 1;
16415 }
16416
16417#ifdef HAVE_MONGOOSE6
16418 if (init_allowed_hosts() != SUCCESS) {
16419 printf("init_allowed_hosts() failed, see messages and midas.log, bye!\n");
16421 return 1;
16422 }
16423
16424 if (verbose) {
16425 if (gAllowedHosts.size() > 0) {
16426 printf("mhttpd allowed hosts list: ");
16427 for (unsigned int i=0; i<gAllowedHosts.size(); i++) {
16428 if (i>0)
16429 printf(", ");
16430 printf("%s", gAllowedHosts[i].c_str());
16431 }
16432 printf("\n");
16433 } else {
16434 printf("mhttpd allowed hosts list is empty\n");
16435 }
16436 }
16437
16438 // populate the MIME.types table
16439 SaveMimetypes(odb->Chdir("WebServer/mime.types", true));
16440#endif
16441
16442 /* initialize odb entries needed for mhttpd and midas web pages */
16443 init_mhttpd_odb(odb);
16444
16445 /* initialize menu buttons */
16446 init_menu_buttons(odb);
16447
16448 /* initialize elog odb entries */
16449 init_elog_odb();
16450
16451 /* initialize the JSON RPC handlers */
16452 mjsonrpc_init();
16454
16456
16457#ifdef HAVE_MONGOOSE6
16459 if (status != SUCCESS) {
16460 // At least print something!
16461 printf("could not start the mongoose web server, see messages and midas.log, bye!\n");
16463 return 1;
16464 }
16465#endif
16466
16467#ifdef HAVE_MONGOOSE616
16468
16469#ifdef SIGPIPE
16470#ifdef SIG_IGN
16472#endif
16473#endif
16474
16475 if (!gTraceBuf) {
16477 }
16478
16479 //if (!request_mutex) {
16480 // status = ss_mutex_create(&request_mutex, FALSE);
16481 // assert(status==SS_SUCCESS || status==SS_CREATED);
16482 //}
16483
16484 /* establish Ctrl-C handler - will set _abort to TRUE */
16486
16487 MVOdb* o = odb->Chdir("WebServer", true);
16489 if (status != SUCCESS) {
16490 // At least print something!
16491 printf("Error: Could not start the mongoose web server, see messages and midas.log, bye!\n");
16493 return 1;
16494 }
16495
16496 delete o;
16497#endif
16498
16499#ifdef HAVE_MONGOOSE6
16500 loop_mg();
16501 stop_mg();
16502#endif
16503
16504#ifdef HAVE_MONGOOSE616
16505 while (!_abort) {
16506
16507 /* cm_yield() is not thread safe, need to take a lock */
16508
16509 //status = ss_mutex_wait_for(request_mutex, 0);
16510 gMutex.lock();
16511
16512 /* check for shutdown message */
16513 status = cm_yield(0);
16514 if (status == RPC_SHUTDOWN)
16515 break;
16516
16517 gMutex.unlock();
16518 //status = ss_mutex_release(request_mutex);
16519
16520 //ss_sleep(10);
16521
16522 mongoose_poll(10);
16523 }
16524
16526#endif
16527
16528 if (gMh) {
16529 delete gMh;
16530 gMh = NULL;
16531 gMhkey = 0;
16532 }
16533
16534 mjsonrpc_exit();
16536 return 0;
16537}
static void usage()
INT cm_yield(INT millisec)
Definition midas.cxx:5642
INT cm_start_watchdog_thread()
Definition midas.cxx:7355
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
Definition midas.cxx:2297
INT cm_disconnect_experiment(void)
Definition midas.cxx:2846
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2134
#define CM_WRONG_PASSWORD
Definition midas.h:589
#define DB_INVALID_HANDLE
Definition midas.h:635
#define RPC_SHUTDOWN
Definition midas.h:707
void mjsonrpc_init()
void mjsonrpc_exit()
void mjsonrpc_set_std_mutex(void *mutex)
INT ss_getpid(void)
Definition system.cxx:1377
INT ss_daemon_init(BOOL keep_stdout)
Definition system.cxx:2001
void * ss_ctrlc_handler(void(*func)(int))
Definition system.cxx:3899
std::string cm_get_error(INT code)
Definition midas.cxx:455
BOOL daemon
Definition mana.cxx:258
static bool trace_mg_send
Definition mhttpd.cxx:13707
static void add_rpc_functions()
Definition mhttpd.cxx:16202
INT check_odb_records(MVOdb *odb)
Definition mhttpd.cxx:13389
void init_elog_odb()
Definition mhttpd.cxx:1978
static void SaveMimetypes(MVOdb *odb)
Definition mhttpd.cxx:201
void ctrlc_handler(int sig)
Definition mhttpd.cxx:13453
static std::vector< std::string > gAllowedHosts
Definition mhttpd.cxx:13463
void init_mhttpd_odb(MVOdb *odb)
Definition mhttpd.cxx:1930
void init_menu_buttons(MVOdb *odb)
Definition mhttpd.cxx:1890
static bool trace_mg_recv
Definition mhttpd.cxx:13706
#define DEFAULT_WATCHDOG_TIMEOUT
Definition midas.h:290
#define DEFAULT_ODB_SIZE
Definition midas.h:270
Here is the call graph for this function:

◆ mgstr()

static std::string mgstr ( const mg_str s)
static

Definition at line 14136 of file mhttpd.cxx.

14137{
14138 return std::string(s->p, s->len);
14139}
Here is the caller graph for this function:

◆ mhttpd_revision()

const char * mhttpd_revision ( void  )

Definition at line 834 of file mhttpd.cxx.

835{
836 return cm_get_revision();
837}
const char * cm_get_revision()
Definition midas.cxx:1484
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mktime_with_dst()

time_t mktime_with_dst ( const struct tm ptms)

Definition at line 9745 of file mhttpd.cxx.

9746{
9747 // this silly stuff is required to correctly handle daylight savings time (Summer time/Winter time)
9748 // when we fill "struct tm" from user input, we cannot know if daylight savings time is in effect
9749 // and we do not know how to initialize the value of tms.tm_isdst.
9750 // This can cause the output of mktime() to be off by one hour.
9751 // (Rules for daylight savings time are set by national and local govt and in some locations, changes yearly)
9752 // (There are no locations with 2 hour or half-hour daylight savings that I know of)
9753 // (Yes, "man mktime" talks about using "tms.tm_isdst = -1")
9754 //
9755 // We assume the user is using local time and we convert in two steps:
9756 //
9757 // first we convert "struct tm" to "time_t" using mktime() with unknown tm_isdst
9758 // second we convert "time_t" back to "struct tm" using localtime_r()
9759 // this fills "tm_isdst" with correct value from the system time zone database
9760 // then we reset all the time fields (except for sub-minute fields not affected by daylight savings)
9761 // and call mktime() again, now with the correct value of "tm_isdst".
9762 // K.O. 2013-09-14
9763
9764 struct tm tms = *ptms;
9765 struct tm tms2;
9766 time_t t1 = ss_mktime(&tms);
9767 localtime_r(&t1, &tms2);
9768 tms2.tm_year = ptms->tm_year;
9769 tms2.tm_mon = ptms->tm_mon;
9770 tms2.tm_mday = ptms->tm_mday;
9771 tms2.tm_hour = ptms->tm_hour;
9772 tms2.tm_min = ptms->tm_min;
9773 time_t t2 = ss_mktime(&tms2);
9774 //printf("t1 %.0f, t2 %.0f, diff %d\n", (double)t1, (double)t2, (int)(t1-t2));
9775 return t2;
9776}
time_t ss_mktime(struct tm *tms)
Definition system.cxx:3365
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mongoose_passwords_enabled()

static bool mongoose_passwords_enabled ( const struct mg_connection nc)
static
Here is the caller graph for this function:

◆ NextHistPlotColour()

static std::string NextHistPlotColour ( const HistPlot hp)
static

Definition at line 10116 of file mhttpd.cxx.

10117{
10118 const char* const colour[] =
10119 {
10120 "#00AAFF", "#FF9000", "#FF00A0", "#00C030",
10121 "#A0C0D0", "#D0A060", "#C04010", "#807060",
10122 "#F0C000", "#2090A0", "#D040D0", "#90B000",
10123 "#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0",
10124 NULL };
10125
10126 for (int i=0; colour[i]; i++) {
10127 bool in_use = false;
10128
10129 for (size_t j=0; j<hp.vars.size(); j++)
10130 if (hp.vars[j].colour == colour[i]) {
10131 in_use = true;
10132 break;
10133 }
10134
10135 if (!in_use)
10136 return colour[i];
10137 }
10138
10139 return "#808080";
10140}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ NextHistPlotOrder()

static int NextHistPlotOrder ( const HistPlot hp)
static

Definition at line 10142 of file mhttpd.cxx.

10143{
10144 int order = 0;
10145 for (size_t i=0; i<hp.vars.size(); i++)
10146 if (hp.vars[i].order > order)
10147 order = hp.vars[i].order;
10148 return order + 10;
10149}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_resource_file()

bool open_resource_file ( const char filename,
std::string *  ppath,
FILE **  pfp 
)

Definition at line 1029 of file mhttpd.cxx.

1030{
1031 // resource file names should not start with a directory separator "/"
1032 // or contain ".." as this will allow them to escape the mhttpd filename "jail"
1033 // by asking file files names like "../../etc/passwd", etc.
1034
1035 if (strlen(filename) < 1) {
1036 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' is too short",
1037 filename);
1038 return false;
1039 }
1040
1041 if (filename[0] == DIR_SEPARATOR) {
1042 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' starting with \'%c\' which is not allowed",
1043 filename, DIR_SEPARATOR);
1044 return false;
1045 }
1046
1047 if (strstr(filename, "..") != NULL) {
1048 cm_msg(MERROR, "open_resource_file", "Invalid resource file name \'%s\' containing \'..\' which is not allowed",
1049 filename);
1050 return false;
1051 }
1052
1053 std::vector<std::string> paths = get_resource_paths();
1054
1055 std::vector<std::string> paths_not_found;
1056
1057 for (unsigned i=0; i<paths.size(); i++) {
1058 std::string path = paths[i];
1059 if (path.length() < 1)
1060 continue;
1061 if (path[0] == '#')
1062 continue;
1063
1064 // expand env.variables before we add the filename.
1065 // the filename comes from the URL and if the URL
1066 // has '$' characters we will try to expand them
1067 // as an env.variable and maybe escape the file jail.
1068
1069 std::string xpath = cm_expand_env(path.c_str());
1070
1071 if (xpath[xpath.length()-1] != DIR_SEPARATOR)
1073 xpath += filename;
1074
1075 //printf("path [%s] [%s] [%s]\n", paths[i].c_str(), path.c_str(), xpath.c_str());
1076
1077 FILE* fp = fopen(xpath.c_str(), "r");
1078 if (fp) {
1079 struct stat statbuf;
1080 int status = fstat(fileno(fp), &statbuf);
1081 if (status != 0) {
1082 cm_msg(MERROR, "open_resource_file", "Cannot fstat() file \'%s\', error %d (%s)", xpath.c_str(), errno, strerror(errno));
1083 fclose(fp);
1084 fp = NULL;
1085 }
1086
1087 if (statbuf.st_mode & S_IFREG) {
1088 // good, normal file
1089 //printf("%s: regular!\n", xpath.c_str());
1090 //} else if (statbuf.st_mode & S_IFLNK) {
1091 // symlink
1092 //printf("%s: symlink!\n", xpath.c_str());
1093 } else if (statbuf.st_mode & S_IFDIR) {
1094 cm_msg(MERROR, "open_resource_file", "File \'%s\' for resource \'%s\' is a directory", xpath.c_str(), filename);
1095 fclose(fp);
1096 fp = NULL;
1097 } else {
1098 cm_msg(MERROR, "open_resource_file", "File \'%s\' for resource \'%s\' is not a regular file, st_mode is 0x%08x", xpath.c_str(), filename, statbuf.st_mode);
1099 fclose(fp);
1100 fp = NULL;
1101 }
1102
1103 if (fp) {
1104 if (ppath)
1105 *ppath = xpath;
1106 if (pfp) {
1107 *pfp = fp;
1108 } else {
1109 fclose(fp);
1110 fp = NULL;
1111 }
1112 //cm_msg(MINFO, "open_resource_file", "Resource file \'%s\' is \'%s\'", filename, xpath.c_str());
1113 return true;
1114 }
1115 }
1116
1117 paths_not_found.push_back(xpath);
1118 }
1119
1120 std::string s;
1121 for (unsigned i=0; i<paths_not_found.size(); i++) {
1122 if (i>0)
1123 s += ", ";
1124 s += paths_not_found[i];
1125 }
1126
1127 cm_msg(MERROR, "open_resource_file", "Cannot find resource file \'%s\', tried %s", filename, s.c_str());
1128 return false;
1129}
std::string cm_expand_env(const char *str)
Definition midas.cxx:7710
std::vector< std::string > get_resource_paths()
Definition mhttpd.cxx:989
static FILE * fp
Here is the call graph for this function:
Here is the caller graph for this function:

◆ output_key()

void output_key ( Param p,
Return r,
HNDLE  hkey,
int  index,
const char format 
)

Definition at line 4368 of file mhttpd.cxx.

4369{
4370 int size, i;
4371 HNDLE hDB, hsubkey;
4372 KEY key;
4373 char data[TEXT_SIZE];
4374
4376
4377 db_get_key(hDB, hkey, &key);
4378 if (key.type == TID_KEY) {
4379 for (i=0 ; ; i++) {
4381 if (!hsubkey)
4382 break;
4383 output_key(p, r, hsubkey, -1, format);
4384 }
4385 } else {
4386 if (key.item_size <= (int)sizeof(data)) {
4387 size = sizeof(data);
4388 db_get_data(hDB, hkey, data, &size, key.type);
4389 if (index == -1) {
4390 for (i=0 ; i<key.num_values ; i++) {
4391 if (p->isparam("name") && atoi(p->getparam("name")) == 1) {
4392 if (key.num_values == 1)
4393 r->rsprintf("%s:", key.name);
4394 else
4395 r->rsprintf("%s[%d]:", key.name, i);
4396 }
4397 std::string data_str;
4398 if (format && format[0])
4400 else
4402 r->rsputs(data_str.c_str());
4403 if (i<key.num_values-1)
4404 r->rsputs("\n");
4405 }
4406 } else {
4407 if (p->isparam("name") && atoi(p->getparam("name")) == 1)
4408 r->rsprintf("%s[%d]:", key.name, index);
4409 if (index >= key.num_values)
4410 r->rsputs("<DB_OUT_OF_RANGE>");
4411 else {
4412 std::string data_str;
4413 if (p->isparam("format"))
4415 else
4417 r->rsputs(data_str.c_str());
4418 }
4419 }
4420 r->rsputs("\n");
4421 }
4422 }
4423}
INT db_sprintff(char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10919
Here is the call graph for this function:
Here is the caller graph for this function:

◆ PrintHistPlot()

static void PrintHistPlot ( const HistPlot hp)
static

Definition at line 10106 of file mhttpd.cxx.

10107{
10108 printf("hist plot: %d variables\n", (int)hp.vars.size());
10109 printf("timescale: %s, minimum: %f, maximum: %f, zero_ylow: %d, log_axis: %d, show_run_markers: %d, show_values: %d, show_fill: %d, show_factor %d, enable_factor: %d\n", hp.timescale.c_str(), hp.minimum, hp.maximum, hp.zero_ylow, hp.log_axis, hp.show_run_markers, hp.show_values, hp.show_fill, hp.show_factor, hp.enable_factor);
10110
10111 for (size_t i=0; i<hp.vars.size(); i++) {
10112 printf("var[%d] event [%s][%s] formula [%s], colour [%s] label [%s] show_raw_value %d factor %f offset %f voffset %f order %d\n", (int)i, hp.vars[i].event_name.c_str(), hp.vars[i].tag_name.c_str(), hp.vars[i].formula.c_str(), hp.vars[i].colour.c_str(), hp.vars[i].label.c_str(), hp.vars[i].show_raw_value, hp.vars[i].factor, hp.vars[i].offset , hp.vars[i].voffset, hp.vars[i].order);
10113 }
10114}
Here is the call graph for this function:

◆ read_history()

int read_history ( const HistPlot hp,
int  index,
int  flags,
time_t  tstart,
time_t  tend,
time_t  scale,
HistoryData data 
)

Definition at line 8356 of file mhttpd.cxx.

8357{
8358 //HNDLE hkeypanel, hkeydvar, hkey;
8359 //KEY key;
8360 //char path[256];
8361 //int n_vars;
8362 int status;
8363 int debug = 1;
8364
8365 //mstrlcpy(path, group, sizeof(path));
8366 //mstrlcat(path, "/", sizeof(path));
8367 //mstrlcat(path, panel, sizeof(path));
8368
8369 //printf("read_history, path %s, index %d, flags 0x%x, start %d, end %d, scale %d, data %p\n", path, index, flags, (int)tstart, (int)tend, (int)scale, data);
8370
8371 /* connect to history */
8373 if (mh == NULL) {
8374 //r->rsprintf(str, "History is not configured\n");
8375 return HS_FILE_ERROR;
8376 }
8377
8378#if 0
8379 /* check panel name in ODB */
8380 status = db_find_key(hDB, 0, "/History/Display", &hkey);
8381 if (!hkey) {
8382 cm_msg(MERROR, "read_history", "Cannot find \'/History/Display\' in ODB, status %d", status);
8383 return HS_FILE_ERROR;
8384 }
8385
8386 /* check panel name in ODB */
8387 status = db_find_key(hDB, hkey, path, &hkeypanel);
8388 if (!hkeypanel) {
8389 cm_msg(MERROR, "read_history", "Cannot find \'%s\' in ODB, status %d", path, status);
8390 return HS_FILE_ERROR;
8391 }
8392
8393 status = db_find_key(hDB, hkeypanel, "Variables", &hkeydvar);
8394 if (!hkeydvar) {
8395 cm_msg(MERROR, "read_history", "Cannot find \'%s/Variables\' in ODB, status %d", path, status);
8396 return HS_FILE_ERROR;
8397 }
8398
8401#endif
8402
8403 data->Allocate(hp.vars.size()+2);
8404
8405 data->tstart = tstart;
8406 data->tend = tend;
8407 data->scale = scale;
8408
8409 for (size_t i=0; i<hp.vars.size(); i++) {
8410 if (index != -1 && (size_t)index != i)
8411 continue;
8412
8413 //char str[256];
8414 //int size = sizeof(str);
8415 //status = db_get_data_index(hDB, hkeydvar, str, &size, i, TID_STRING);
8416 //if (status != DB_SUCCESS) {
8417 // cm_msg(MERROR, "read_history", "Cannot read tag %d in panel %s, status %d", i, path, status);
8418 // continue;
8419 //}
8420
8421 /* split varname in event, variable and index: "event/tag[index]" */
8422
8423 //char *p = strchr(str, ':');
8424 //if (!p)
8425 // p = strchr(str, '/');
8426 //
8427 //if (!p) {
8428 // cm_msg(MERROR, "read_history", "Tag \"%s\" has wrong format in panel \"%s\"", str, path);
8429 // continue;
8430 //}
8431
8432 //*p = 0;
8433
8434 data->odb_index[data->nvars] = i;
8435 data->event_names[data->nvars] = STRDUP(hp.vars[i].event_name.c_str());
8436 data->var_names[data->nvars] = STRDUP(hp.vars[i].tag_name.c_str());
8437 data->var_index[data->nvars] = 0;
8438
8439 char *q = strchr(data->var_names[data->nvars], '[');
8440 if (q) {
8441 data->var_index[data->nvars] = atoi(q+1);
8442 *q = 0;
8443 }
8444
8445 data->nvars++;
8446 } // loop over variables
8447
8448 /* write run markes if selected */
8449 if (flags & READ_HISTORY_RUNMARKER) {
8450
8451 data->event_names[data->nvars+0] = STRDUP("Run transitions");
8452 data->event_names[data->nvars+1] = STRDUP("Run transitions");
8453
8454 data->var_names[data->nvars+0] = STRDUP("State");
8455 data->var_names[data->nvars+1] = STRDUP("Run number");
8456
8457 data->var_index[data->nvars+0] = 0;
8458 data->var_index[data->nvars+1] = 0;
8459
8460 data->odb_index[data->nvars+0] = -1;
8461 data->odb_index[data->nvars+1] = -2;
8462
8463 data->nvars += 2;
8464 }
8465
8466 bool get_last_written = false;
8467
8468 if (flags & READ_HISTORY_DATA) {
8469 status = mh->hs_read(tstart, tend, scale,
8470 data->nvars,
8471 data->event_names,
8472 data->var_names,
8473 data->var_index,
8474 data->num_entries,
8475 data->t,
8476 data->v,
8477 data->status);
8478
8479 if (debug) {
8480 printf("read_history: nvars %d, hs_read() status %d\n", data->nvars, status);
8481 for (int i=0; i<data->nvars; i++) {
8482 printf("read_history: %d: event [%s], var [%s], index %d, odb index %d, status %d, num_entries %d\n", i, data->event_names[i], data->var_names[i], data->var_index[i], data->odb_index[i], data->status[i], data->num_entries[i]);
8483 }
8484 }
8485
8486 if (status != HS_SUCCESS) {
8487 cm_msg(MERROR, "read_history", "Complete history failure, hs_read() status %d, see messages", status);
8488 return HS_FILE_ERROR;
8489 }
8490
8491 for (int i=0; i<data->nvars; i++) {
8492 if (data->status[i] != HS_SUCCESS || data->num_entries[i] < 1) {
8493 get_last_written = true;
8494 break;
8495 }
8496 }
8497 }
8498
8499 if (flags & READ_HISTORY_LAST_WRITTEN)
8500 get_last_written = true;
8501
8502 if (get_last_written) {
8503 data->have_last_written = true;
8504
8506 tstart,
8507 data->nvars,
8508 data->event_names,
8509 data->var_names,
8510 data->var_index,
8511 data->last_written);
8512
8513 if (status != HS_SUCCESS) {
8514 data->have_last_written = false;
8515 }
8516 }
8517
8518 return SUCCESS;
8519}
virtual int hs_get_last_written(time_t start_time, int num_var, const char *const event_name[], const char *const tag_name[], const int var_index[], time_t last_written[])=0
static std::string q(const char *s)
#define STRDUP(x)
Definition mhttpd.cxx:8237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_passwords()

static bool read_passwords ( Auth auth)
static

Definition at line 13796 of file mhttpd.cxx.

13797{
13798 std::string path;
13799 FILE *fp;
13800 int status = find_file_mg("htpasswd.txt", path, &fp, trace_mg||verbose_mg);
13801
13802 auth->passwd_filename = path;
13803 auth->passwords.clear();
13804
13805 if (status != SUCCESS || fp == NULL) {
13806 cm_msg(MERROR, "mongoose", "mongoose web server cannot find password file \"%s\"", path.c_str());
13807 cm_msg(MERROR, "mongoose", "please create password file: touch %s", path.c_str());
13808 return false;
13809 }
13810
13811 bool have_realm = false;
13812 char buf[256];
13813
13814 /*
13815 * Read passwords file line by line. If should have htdigest format,
13816 * i.e. each line should be a colon-separated sequence:
13817 * USER_NAME:DOMAIN_NAME:HA1_HASH_OF_USER_DOMAIN_AND_PASSWORD
13818 */
13819 while (fgets(buf, sizeof(buf), fp) != NULL) {
13820 char f_user[256];
13821 char f_domain[256];
13822 char f_ha1[256];
13823
13824 if (sscanf(buf, "%[^:]:%[^:]:%s", f_user, f_domain, f_ha1) == 3) {
13825 AuthEntry e;
13826 e.realm = f_domain;
13827 e.username = f_user;
13828 e.password = f_ha1;
13829
13830 if (e.realm == auth->realm) {
13831 have_realm = true;
13832 auth->passwords.push_back(e);
13833 }
13834 }
13835 }
13836
13837 fclose(fp);
13838
13839 return have_realm;
13840}
int find_file_mg(const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13672
std::string realm
Definition mhttpd.cxx:13718
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect()

void redirect ( Return r,
const char path 
)

Definition at line 1407 of file mhttpd.cxx.

1408{
1409 char str[256];
1410
1411 //printf("redirect to [%s]\n", path);
1412
1413 mstrlcpy(str, path, sizeof(str));
1414 if (str[0] == 0)
1415 strcpy(str, "./");
1416
1417 /* redirect */
1418 r->rsprintf("HTTP/1.1 302 Found\r\n");
1419 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1420 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1421
1422 if (strncmp(path, "http:", 5) == 0)
1423 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1424 else if (strncmp(path, "https:", 6) == 0)
1425 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1426 else {
1427 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1428 }
1429}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect2()

void redirect2 ( Return r,
const char path 
)

Definition at line 1444 of file mhttpd.cxx.

1445{
1446 redirect(r, path);
1447}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ redirect_307()

void redirect_307 ( Return r,
const char path 
)

Definition at line 1431 of file mhttpd.cxx.

1432{
1433 //printf("redirect_307 to [%s]\n", path);
1434
1435 /* redirect */
1436 r->rsprintf("HTTP/1.1 307 Temporary Redirect\r\n");
1437 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1438 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1439 r->rsprintf("Location: %s\r\n", path);
1440 r->rsprintf("\r\n");
1441 r->rsprintf("<html>redirect to %s</html>\r\n", path);
1442}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveHistPlotToOdb()

static void SaveHistPlotToOdb ( MVOdb odb,
const HistPlot hp,
const char group,
const char panel 
)
static

Definition at line 10405 of file mhttpd.cxx.

10406{
10407 if (strlen(group) < 1) {
10408 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid group name", group, panel);
10409 return;
10410 }
10411
10412 if (strlen(panel) < 1) {
10413 cm_msg(MERROR, "SaveHistPlotToOdb", "Error: Cannot write history plot to ODB, group \"%s\", panel \"%s\", invalid panel name", group, panel);
10414 return;
10415 }
10416
10417 std::string path = "History/Display/";
10418 path += group;
10419 path += "/";
10420 path += panel;
10421
10422// printf("Save to ODB %s: ", path.c_str());
10423// PrintHistPlot(hp);
10424
10425 MVOdb* o = odb->Chdir(path.c_str(), true);
10426
10427 o->WS("Timescale", hp.timescale.c_str());
10428 o->WD("Minimum", hp.minimum);
10429 o->WD("Maximum", hp.maximum);
10430 o->WB("Zero ylow", hp.zero_ylow);
10431 o->WB("Log axis", hp.log_axis);
10432 o->WB("Show run markers", hp.show_run_markers);
10433 o->WB("Show values", hp.show_values);
10434 o->WB("Show fill", hp.show_fill);
10435 o->WB("Show factor and offset", hp.show_factor);
10436 //o->WB("Enable factor and offset", hp.enable_factor);
10437
10438 std::vector<std::string> hist_vars;
10439 std::vector<std::string> hist_formula;
10440 std::vector<std::string> hist_colour;
10441 std::vector<std::string> hist_label;
10442 std::vector<bool> hist_show_raw_value;
10443 std::vector<double> hist_factor;
10444 std::vector<double> hist_offset;
10445 std::vector<double> hist_voffset;
10446
10447 for (size_t i=0; i<hp.vars.size(); i++) {
10448 hist_vars.push_back(hp.vars[i].event_name + ":" + hp.vars[i].tag_name);
10449 hist_formula.push_back(hp.vars[i].formula);
10450 hist_colour.push_back(hp.vars[i].colour);
10451 hist_label.push_back(hp.vars[i].label);
10452 hist_show_raw_value.push_back(hp.vars[i].show_raw_value);
10453 hist_factor.push_back(hp.vars[i].factor);
10454 hist_offset.push_back(hp.vars[i].offset);
10455 hist_voffset.push_back(hp.vars[i].voffset);
10456 }
10457
10458 if (hp.vars.size() > 0) {
10459 o->WSA("Variables", hist_vars, 64);
10460 o->WSA("Formula", hist_formula, 64);
10461 o->WSA("Colour", hist_colour, NAME_LENGTH);
10462 o->WSA("Label", hist_label, NAME_LENGTH);
10463 o->WBA("Show raw value", hist_show_raw_value);
10464 o->WDA("Factor", hist_factor);
10465 o->WDA("Offset", hist_offset);
10466 o->WDA("VOffset", hist_voffset);
10467 } else {
10468 o->Delete("Variables");
10469 o->Delete("Formula");
10470 o->Delete("Colour");
10471 o->Delete("Label");
10472 o->Delete("Show raw value");
10473 o->Delete("Factor");
10474 o->Delete("Offset");
10475 o->Delete("VOffset");
10476 }
10477
10478 delete o;
10479}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SaveMimetypes()

static void SaveMimetypes ( MVOdb odb)
static

Definition at line 201 of file mhttpd.cxx.

202{
203 gMimeTypesOdb = odb;
204
205 for (int i=0; gMimetypeTable[i].ext.length() > 0; i++) {
206 std::string tmp = gMimetypeTable[i].mimetype;
207 gMimeTypesOdb->RS(gMimetypeTable[i].ext.c_str(), &tmp, true);
208 }
209}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_callback()

INT search_callback ( HNDLE  hDB,
HNDLE  hKey,
KEY key,
INT  level,
void info 
)

Definition at line 1457 of file mhttpd.cxx.

1458{
1460 int i;
1461 INT size, status;
1462
1463 Return* r = sinfo->r;
1464 const char* search_name = sinfo->search_name;
1465
1466 /* convert strings to uppercase */
1467
1468 char xstr1[MAX_ODB_PATH];
1469 for (i = 0; key->name[i]; i++)
1470 xstr1[i] = toupper(key->name[i]);
1471 xstr1[i] = 0;
1472
1473 char str2[MAX_ODB_PATH];
1474 for (i = 0; search_name[i] ; i++)
1475 str2[i] = toupper(search_name[i]);
1476 str2[i] = 0;
1477
1478 if (strstr(xstr1, str2) != NULL) {
1479 char data[10000];
1480 std::string path = db_get_path(hDB, hKey).substr(1);
1481 std::string path_encoded = urlEncode(path.c_str());
1482
1483 if (key->type == TID_KEY || key->type == TID_LINK) {
1484 /* for keys, don't display data value */
1485 r->rsprintf("<tr><td class=\"ODBkey\"><a href=\"?cmd=odb&odb_path=/%s\">/%s</a></tr>\n", path_encoded.c_str(), path.c_str());
1486 } else {
1487 /* strip variable name from path */
1488 char* p = const_cast<char *>(path.data() + path.length() - 1);
1489 while (*p && *p != '/')
1490 *p-- = 0;
1491 if (*p == '/')
1492 *p = 0;
1493
1494 /* display single value */
1495 if (key->num_values == 1) {
1496 size = sizeof(data);
1497 status = db_get_data(hDB, hKey, data, &size, key->type);
1498 std::string data_str;
1499 if (status == DB_NO_ACCESS)
1500 data_str = "<no read access>";
1501 else
1503
1504 r->rsprintf("<tr><td class=\"ODBkey\">");
1505 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s</a></td>", path_encoded.c_str(), path.c_str(), key->name);
1506 r->rsprintf("<td class=\"ODBvalue\">%s</td></tr>\n", data_str.c_str());
1507 } else {
1508 /* display first value */
1509 i = key->num_values;
1510 if (i > 10)
1511 i = 11;
1512 r->rsprintf("<tr><td rowspan=%d class=\"ODBkey\">", i);
1513 r->rsprintf("<a href=\"?cmd=odb&odb_path=/%s\">/%s/%s\n", path_encoded.c_str(), path.c_str(), key->name);
1514
1515 for (int i = 0; i < key->num_values; i++) {
1516 size = sizeof(data);
1517 db_get_data_index(hDB, hKey, data, &size, i, key->type);
1518
1519 std::string data_str = db_sprintf(data, key->item_size, 0, key->type);
1520
1521 if (i > 0)
1522 r->rsprintf("<tr>");
1523
1524 r->rsprintf("<td class=\"ODBvalue\">[%d] %s</td></tr>\n", i, data_str.c_str());
1525
1526 if (i > 8) {
1527 r->rsprintf("<tr><td class=\"ODBvalue\">... [%d] values ...</td></tr>\n", key->num_values - i - 1);
1528 break;
1529 }
1530 }
1531 }
1532 }
1533 }
1534
1535 return SUCCESS;
1536}
#define DB_NO_ACCESS
Definition midas.h:648
void ** info
Definition fesimdaq.cxx:41
#define MAX_ODB_PATH
Definition midas.h:277
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sec_to_label()

void sec_to_label ( char result,
int  sec,
int  base,
int  force_date 
)

Definition at line 7750 of file mhttpd.cxx.

7751{
7752 char mon[80];
7753 time_t t_sec;
7754
7755 t_sec = (time_t) sec;
7756
7757 struct tm tms;
7758 localtime_r(&t_sec, &tms);
7759 strcpy(mon, mname[tms.tm_mon]);
7760 mon[3] = 0;
7761
7762 if (force_date) {
7763 if (base < 600)
7764 sprintf(result, "%02d %s %02d %02d:%02d:%02d",
7765 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min,
7766 tms.tm_sec);
7767 else if (base < 3600 * 24)
7768 sprintf(result, "%02d %s %02d %02d:%02d",
7769 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7770 else
7771 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7772 } else {
7773 if (base < 600)
7774 sprintf(result, "%02d:%02d:%02d", tms.tm_hour, tms.tm_min, tms.tm_sec);
7775 else if (base < 3600 * 3)
7776 sprintf(result, "%02d:%02d", tms.tm_hour, tms.tm_min);
7777 else if (base < 3600 * 24)
7778 sprintf(result, "%02d %s %02d %02d:%02d",
7779 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7780 else
7781 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7782 }
7783}
const char * mname[]
Definition midas.cxx:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_file()

bool send_file ( Return r,
const std::string &  path,
bool  generate_404 = true 
)

Definition at line 1210 of file mhttpd.cxx.

1211{
1212 FILE *fp = fopen(path.c_str(), "rb");
1213
1214 if (!fp) {
1215 if (generate_404) {
1216 /* header */
1217 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1218 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1219 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1220 r->rsprintf("\r\n");
1221 r->rsprintf("Error: Cannot read \"%s\", fopen() errno %d (%s)\n", path.c_str(), errno, strerror(errno));
1222 }
1223 return false;
1224 }
1225
1226 return send_fp(r, path, fp);
1227}
bool send_fp(Return *r, const std::string &path, FILE *fp)
Definition mhttpd.cxx:1164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_fp()

bool send_fp ( Return r,
const std::string &  path,
FILE fp 
)

Definition at line 1164 of file mhttpd.cxx.

1165{
1166 assert(fp != NULL);
1167
1168 // send HTTP headers
1169
1170 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1171 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1172 r->rsprintf("Accept-Ranges: bytes\r\n");
1173
1174 // send HTTP cache control headers
1175
1176 time_t now = time(NULL);
1177 now += (int) (3600 * 24);
1178 struct tm gmt_tms;
1179 gmtime_r(&now, &gmt_tms);
1180 const char* format = "%A, %d-%b-%y %H:%M:%S GMT";
1181
1182 char str[256];
1183 strftime(str, sizeof(str), format, &gmt_tms);
1184 r->rsprintf("Expires: %s\r\n", str);
1185
1186 // send Content-Type header
1187
1188 r->rsprintf("Content-Type: %s\r\n", get_content_type(path.c_str()).c_str());
1189
1190 // send Content-Length header
1191
1192 struct stat stat_buf;
1193 fstat(fileno(fp), &stat_buf);
1194 int length = stat_buf.st_size;
1195 r->rsprintf("Content-Length: %d\r\n", length);
1196
1197 // send end of headers
1198
1199 r->rsprintf("\r\n");
1200
1201 // send file data
1202
1203 r->rread(path.c_str(), fileno(fp), length);
1204
1205 fclose(fp);
1206
1207 return true;
1208}
void rread(const char *filename, int fh, int len)
Definition mhttpd.cxx:586
std::string get_content_type(const char *filename)
Definition mhttpd.cxx:1133
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_icon()

void send_icon ( Return r,
const char icon 
)

Definition at line 12188 of file mhttpd.cxx.

12189{
12190 int length;
12191 const unsigned char *picon;
12192 char str[256], format[256];
12193 time_t now;
12194
12195 if (strstr(icon, "favicon.ico") != 0) {
12196 length = sizeof(favicon_ico);
12198 } else if (strstr(icon, "favicon.png") != 0) {
12199 length = sizeof(favicon_png);
12201 } else
12202 return;
12203
12204 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
12205 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12206 r->rsprintf("Accept-Ranges: bytes\r\n");
12207
12208 /* set expiration time to one day */
12209 time(&now);
12210 now += (int) (3600 * 24);
12211 struct tm gmt_tms;
12212 gmtime_r(&now, &gmt_tms);
12213 strcpy(format, "%A, %d-%b-%y %H:%M:%S GMT");
12214 strftime(str, sizeof(str), format, &gmt_tms);
12215 r->rsprintf("Expires: %s\r\n", str);
12216
12217 if (equal_ustring(icon, "favicon.ico"))
12218 r->rsprintf("Content-Type: image/x-icon\r\n");
12219 else
12220 r->rsprintf("Content-Type: image/png\r\n");
12221
12222 r->rsprintf("Content-Length: %d\r\n\r\n", length);
12223
12224 r->rmemcpy(picon, length);
12225}
void rmemcpy(const void *buf, int len)
Definition mhttpd.cxx:576
const unsigned char favicon_png[]
Definition mhttpd.cxx:215
const unsigned char favicon_ico[]
Definition mhttpd.cxx:280
Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_resource()

bool send_resource ( Return r,
const std::string &  name,
bool  generate_404 = true 
)

Definition at line 1229 of file mhttpd.cxx.

1230{
1231 std::string path;
1232 FILE *fp = NULL;
1233
1234 bool found = open_resource_file(name.c_str(), &path, &fp);
1235
1236 if (!found) {
1237 if (generate_404) {
1238 /* header */
1239 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1240 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1241 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1242 r->rsprintf("\r\n");
1243 r->rsprintf("Error: resource file \"%s\" not found, see messages\n", name.c_str());
1244 }
1245 return false;
1246 }
1247
1248 return send_fp(r, path, fp);
1249}
bool open_resource_file(const char *filename, std::string *ppath, FILE **pfp)
Definition mhttpd.cxx:1029
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendmail()

INT sendmail ( const char from_host,
const char smtp_host,
const char from,
const char to,
const char subject,
const char text 
)

Definition at line 1253 of file mhttpd.cxx.

1254{
1255 struct sockaddr_in bind_addr;
1256 struct hostent *phe;
1257 int i, s, strsize, offset;
1258 char *str, buf[256];
1259
1260 if (verbose)
1261 printf("\n\nEmail from %s to %s, SMTP host %s:\n", from, to, smtp_host);
1262
1263 /* create a new socket for connecting to remote server */
1264 s = socket(AF_INET, SOCK_STREAM, 0);
1265 if (s == -1)
1266 return -1;
1267
1268 /* connect to remote node port 25 */
1269 memset(&bind_addr, 0, sizeof(bind_addr));
1270 bind_addr.sin_family = AF_INET;
1271 bind_addr.sin_port = htons((short) 25);
1272
1274 if (phe == NULL)
1275 return -1;
1276 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
1277
1278 if (connect(s, (const sockaddr*)&bind_addr, sizeof(bind_addr)) < 0) {
1279 closesocket(s);
1280 return -1;
1281 }
1282
1283 strsize = TEXT_SIZE + 1000;
1284 str = (char*)malloc(strsize);
1285
1286 recv_string(s, str, strsize, 3000);
1287 if (verbose)
1288 puts(str);
1289
1290 /* drain server messages */
1291 do {
1292 str[0] = 0;
1293 recv_string(s, str, strsize, 300);
1294 if (verbose)
1295 puts(str);
1296 } while (str[0]);
1297
1298 sprintf(str, "HELO %s\r\n", from_host);
1299 send(s, str, strlen(str), 0);
1300 if (verbose)
1301 puts(str);
1302 recv_string(s, str, strsize, 3000);
1303 if (verbose)
1304 puts(str);
1305
1306 if (strchr(from, '<')) {
1307 mstrlcpy(buf, strchr(from, '<') + 1, sizeof(buf));
1308 if (strchr(buf, '>'))
1309 *strchr(buf, '>') = 0;
1310 } else
1311 mstrlcpy(buf, from, sizeof(buf));
1312
1313 sprintf(str, "MAIL FROM: %s\n", buf);
1314 send(s, str, strlen(str), 0);
1315 if (verbose)
1316 puts(str);
1317 recv_string(s, str, strsize, 3000);
1318 if (verbose)
1319 puts(str);
1320
1321 sprintf(str, "RCPT TO: <%s>\r\n", to);
1322 send(s, str, strlen(str), 0);
1323 if (verbose)
1324 puts(str);
1325 recv_string(s, str, strsize, 3000);
1326 if (verbose)
1327 puts(str);
1328
1329 sprintf(str, "DATA\r\n");
1330 send(s, str, strlen(str), 0);
1331 if (verbose)
1332 puts(str);
1333 recv_string(s, str, strsize, 3000);
1334 if (verbose)
1335 puts(str);
1336
1337 sprintf(str, "To: %s\r\nFrom: %s\r\nSubject: %s\r\n", to, from, subject);
1338 send(s, str, strlen(str), 0);
1339 if (verbose)
1340 puts(str);
1341
1342 sprintf(str, "X-Mailer: mhttpd revision %s\r\n", mhttpd_revision());
1343 send(s, str, strlen(str), 0);
1344 if (verbose)
1345 puts(str);
1346
1347 ss_tzset(); // required for localtime_r()
1348 time_t now;
1349 time(&now);
1350 struct tm tms;
1351 localtime_r(&now, &tms);
1352 strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S", &tms);
1353 offset = (-(int) timezone);
1354 if (tms.tm_isdst)
1355 offset += 3600;
1356 sprintf(str, "Date: %s %+03d%02d\r\n", buf, (int) (offset / 3600),
1357 (int) ((abs((int) offset) / 60) % 60));
1358 send(s, str, strlen(str), 0);
1359 if (verbose)
1360 puts(str);
1361
1362 sprintf(str, "Content-Type: TEXT/PLAIN; charset=US-ASCII\r\n\r\n");
1363 send(s, str, strlen(str), 0);
1364 if (verbose)
1365 puts(str);
1366
1367 /* analyze text for "." at beginning of line */
1368 const char* p = text;
1369 str[0] = 0;
1370 while (strstr(p, "\r\n.\r\n")) {
1371 i = (POINTER_T) strstr(p, "\r\n.\r\n") - (POINTER_T) p + 1;
1372 mstrlcat(str, p, i);
1373 p += i + 4;
1374 mstrlcat(str, "\r\n..\r\n", strsize);
1375 }
1376 mstrlcat(str, p, strsize);
1377 mstrlcat(str, "\r\n", strsize);
1378 send(s, str, strlen(str), 0);
1379 if (verbose)
1380 puts(str);
1381
1382 /* send ".<CR>" to signal end of message */
1383 sprintf(str, ".\r\n");
1384 send(s, str, strlen(str), 0);
1385 if (verbose)
1386 puts(str);
1387 recv_string(s, str, strsize, 3000);
1388 if (verbose)
1389 puts(str);
1390
1391 sprintf(str, "QUIT\n");
1392 send(s, str, strlen(str), 0);
1393 if (verbose)
1394 puts(str);
1395 recv_string(s, str, strsize, 3000);
1396 if (verbose)
1397 puts(str);
1398
1399 closesocket(s);
1400 free(str);
1401
1402 return 1;
1403}
INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
Definition system.cxx:5393
#define closesocket(s)
Definition melog.cxx:29
static int offset
Definition mgd.cxx:1500
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_http_trace()

static MJsonNode * set_http_trace ( const MJsonNode *  params)
static

Definition at line 16188 of file mhttpd.cxx.

16189{
16190 if (!params) {
16191 MJSO* doc = MJSO::I();
16192 doc->D("set new value of mhttpd http_trace");
16193 doc->P(NULL, MJSON_INT, "new value of http_trace");
16194 doc->R(NULL, MJSON_INT, "new value of http_trace");
16195 return doc;
16196 }
16197
16198 http_trace = params->GetInt();
16199 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16200}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_cnaf_page()

static void show_cnaf_page ( Param p,
Return rr 
)
static

Definition at line 5653 of file mhttpd.cxx.

5654{
5655 char str[256];
5656 int c, n, a, f, d, q, x, r, ia, id, w;
5657 int i, size, status;
5659
5660 static char client_name[NAME_LENGTH];
5661 static HNDLE hconn = 0;
5662
5664
5665 /* find FCNA server if not specified */
5666 if (hconn == 0) {
5667 /* find client which exports FCNA function */
5668 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
5669 if (status == DB_SUCCESS) {
5670 for (i = 0;; i++) {
5673 break;
5674
5675 sprintf(str, "RPC/%d", RPC_CNAF16);
5677 if (status == DB_SUCCESS) {
5678 size = sizeof(client_name);
5679 db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, TRUE);
5680 break;
5681 }
5682 }
5683 }
5684
5685 if (client_name[0]) {
5686 status = cm_connect_client(client_name, &hconn);
5687 if (status != RPC_SUCCESS)
5688 hconn = 0;
5689 }
5690 }
5691
5692 /* header */
5693 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
5694 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
5695 rr->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
5696
5697 rr->rsprintf("<html><head>\n");
5698 rr->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
5699 rr->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
5700 rr->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
5701 rr->rsprintf("<title>MIDAS CAMAC interface</title></head>\n");
5702 rr->rsprintf("<body><form method=\"GET\" action=\"CNAF\">\n\n");
5703
5704 /* title row */
5705
5706 size = sizeof(str);
5707 str[0] = 0;
5708 db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
5709
5710 rr->rsprintf("<table border=3 cellpadding=1>\n");
5711 rr->rsprintf("<tr><th colspan=3>MIDAS experiment \"%s\"", str);
5712
5713 if (client_name[0] == 0)
5714 rr->rsprintf("<th colspan=3 class=\"redLight\">No CAMAC server running</tr>\n");
5715 else if (hconn == 0)
5716 rr->rsprintf("<th colspan=3 class=\"redLight\">Cannot connect to %s</tr>\n", client_name);
5717 else
5718 rr->rsprintf("<th colspan=3>CAMAC server: %s</tr>\n", client_name);
5719
5720 /* default values */
5721 c = n = 1;
5722 a = f = d = q = x = 0;
5723 r = 1;
5724 ia = id = w = 0;
5725
5726 /*---- menu buttons ----*/
5727
5728 rr->rsprintf("<tr><td colspan=3>\n");
5729 rr->rsprintf("<input type=submit name=cmd value=Execute>\n");
5730
5731 rr->rsprintf("<td colspan=3>\n");
5732 rr->rsprintf("<input type=submit name=cmd value=ODB>\n");
5733 rr->rsprintf("<input type=submit name=cmd value=Status>\n");
5734 rr->rsprintf("<input type=submit name=cmd value=Help>\n");
5735 rr->rsprintf("</tr>\n\n");
5736
5737 /* header */
5738 rr->rsprintf("<tr><th>N");
5739 rr->rsprintf("<th>A");
5740 rr->rsprintf("<th>F");
5741 rr->rsprintf("<th colspan=3>Data");
5742
5743 /* execute commands */
5744 size = sizeof(d);
5745
5746 const char* cmd = p->getparam("cmd");
5747 if (equal_ustring(cmd, "C cycle")) {
5748 rpc_client_call(hconn, RPC_CNAF16, CNAF_CRATE_CLEAR, 0, 0, 0, 0, 0, &d, &size, &x,
5749 &q);
5750
5751 rr->rsprintf("<tr><td colspan=6 class=\"greenLight\">C cycle executed sucessfully</tr>\n");
5752 } else if (equal_ustring(cmd, "Z cycle")) {
5753 rpc_client_call(hconn, RPC_CNAF16, CNAF_CRATE_ZINIT, 0, 0, 0, 0, 0, &d, &size, &x,
5754 &q);
5755
5756 rr->rsprintf("<tr><td colspan=6 class=\"greenLight\">Z cycle executed sucessfully</tr>\n");
5757 } else if (equal_ustring(cmd, "Clear inhibit")) {
5758 rpc_client_call(hconn, RPC_CNAF16, CNAF_INHIBIT_CLEAR, 0, 0, 0, 0, 0, &d, &size, &x,
5759 &q);
5760
5761 rr->rsprintf
5762 ("<tr><td colspan=6 class=\"greenLight\">Clear inhibit executed sucessfully</tr>\n");
5763 } else if (equal_ustring(cmd, "Set inhibit")) {
5764 rpc_client_call(hconn, RPC_CNAF16, CNAF_INHIBIT_SET, 0, 0, 0, 0, 0, &d, &size, &x,
5765 &q);
5766
5767 rr->rsprintf
5768 ("<tr><td colspan=6 class=\"greenLight\">Set inhibit executed sucessfully</tr>\n");
5769 } else if (equal_ustring(cmd, "Execute")) {
5770 c = atoi(p->getparam("C"));
5771 n = atoi(p->getparam("N"));
5772 a = atoi(p->getparam("A"));
5773 f = atoi(p->getparam("F"));
5774 r = atoi(p->getparam("R"));
5775 w = atoi(p->getparam("W"));
5776 id = atoi(p->getparam("ID"));
5777 ia = atoi(p->getparam("IA"));
5778
5779 const char* pd = p->getparam("D");
5780 if (strncmp(pd, "0x", 2) == 0)
5781 sscanf(pd + 2, "%x", &d);
5782 else
5783 d = atoi(p->getparam("D"));
5784
5785 /* limit repeat range */
5786 if (r == 0)
5787 r = 1;
5788 if (r > 100)
5789 r = 100;
5790 if (w > 1000)
5791 w = 1000;
5792
5793 for (i = 0; i < r; i++) {
5794 status = SUCCESS;
5795
5796 if (hconn) {
5797 size = sizeof(d);
5798 status =
5799 rpc_client_call(hconn, RPC_CNAF24, CNAF, 0, c, n, a, f, &d, &size, &x,
5800 &q);
5801
5802 if (status == RPC_NET_ERROR) {
5803 /* try to reconnect */
5804 //cm_disconnect_client(hconn, FALSE);
5805 status = cm_connect_client(client_name, &hconn);
5806 if (status != RPC_SUCCESS) {
5807 hconn = 0;
5808 client_name[0] = 0;
5809 }
5810
5811 if (hconn) {
5812 status = rpc_client_call(hconn, RPC_CNAF24, CNAF, 0, c, n, a, f, &d, &size, &x, &q);
5813 }
5814 }
5815 }
5816
5817 if (status != SUCCESS) {
5818 rr->rsprintf
5819 ("<tr><td colspan=6 class=\"redLight\">Error executing function, code = %d</tr>",
5820 status);
5821 } else {
5822 rr->rsprintf("<tr align=center><td>%d", n);
5823 rr->rsprintf("<td>%d", a);
5824 rr->rsprintf("<td>%d", f);
5825 rr->rsprintf("<td colspan=3>%d / 0x%04X Q%d X%d", d, d, q, x);
5826 }
5827
5828 d += id;
5829 a += ia;
5830
5831 if (w > 0)
5832 ss_sleep(w);
5833 }
5834 }
5835
5836 /* input fields */
5837 rr->rsprintf
5838 ("<tr align=center><td><input type=text size=3 name=N value=%d>\n",
5839 n);
5840 rr->rsprintf("<td><input type=text size=3 name=A value=%d>\n", a);
5841 rr->rsprintf("<td><input type=text size=3 name=F value=%d>\n", f);
5842 rr->rsprintf
5843 ("<td colspan=3><input type=text size=8 name=D value=%d></tr>\n",
5844 d);
5845
5846 /* control fields */
5847 rr->rsprintf("<tr><td colspan=2>Repeat");
5848 rr->rsprintf("<td><input type=text size=3 name=R value=%d>\n", r);
5849
5850 rr->rsprintf
5851 ("<td align=center colspan=3><input type=submit name=cmd value=\"C cycle\">\n");
5852 rr->rsprintf("<input type=submit name=cmd value=\"Z cycle\">\n");
5853
5854 rr->rsprintf("<tr><td colspan=2>Repeat delay [ms]");
5855 rr->rsprintf("<td><input type=text size=3 name=W value=%d>\n", w);
5856
5857 rr->rsprintf
5858 ("<td align=center colspan=3><input type=submit name=cmd value=\"Set inhibit\">\n");
5859 rr->rsprintf("<input type=submit name=cmd value=\"Clear inhibit\">\n");
5860
5861 rr->rsprintf("<tr><td colspan=2>Data increment");
5862 rr->rsprintf("<td><input type=text size=3 name=ID value=%d>\n", id);
5863
5864 rr->rsprintf
5865 ("<td colspan=3 align=center>Branch <input type=text size=3 name=B value=0>\n");
5866
5867 rr->rsprintf("<tr><td colspan=2>A increment");
5868 rr->rsprintf("<td><input type=text size=3 name=IA value=%d>\n", ia);
5869
5870 rr->rsprintf
5871 ("<td colspan=3 align=center>Crate <input type=text size=3 name=C value=%d>\n",
5872 c);
5873
5874 rr->rsprintf("</table></body>\r\n");
5875}
#define RPC_NET_ERROR
Definition midas.h:701
INT ss_sleep(INT millisec)
Definition system.cxx:3628
#define RPC_CNAF16
Definition mrpc.h:125
#define RPC_CNAF24
Definition mrpc.h:126
#define CNAF_INHIBIT_SET
Definition midas.h:494
#define CNAF_CRATE_ZINIT
Definition midas.h:497
#define CNAF
Definition midas.h:491
#define CNAF_CRATE_CLEAR
Definition midas.h:496
#define CNAF_INHIBIT_CLEAR
Definition midas.h:495
double d
Definition system.cxx:1311
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_file()

void show_custom_file ( Return r,
const char name 
)

Definition at line 3609 of file mhttpd.cxx.

3610{
3611 char str[256];
3612 std::string filename;
3613 HNDLE hDB;
3614
3616
3617 HNDLE hkey;
3618 sprintf(str, "/Custom/%s", name);
3619 db_find_key(hDB, 0, str, &hkey);
3620
3621 if (!hkey) {
3622 sprintf(str, "/Custom/%s&", name);
3623 db_find_key(hDB, 0, str, &hkey);
3624 if (!hkey) {
3625 sprintf(str, "/Custom/%s!", name);
3626 db_find_key(hDB, 0, str, &hkey);
3627 }
3628 }
3629
3630 if(!hkey){
3631 sprintf(str,"show_custom_file: Invalid custom page: \"/Custom/%s\" not found in ODB", name);
3632 show_error_404(r, str);
3633 return;
3634 }
3635
3636 int status;
3637 KEY key;
3638
3640
3641 if (status != DB_SUCCESS) {
3642 char errtext[512];
3643 sprintf(errtext, "show_custom_file: Error: db_get_key() for \"%s\" status %d", str, status);
3645 return;
3646 }
3647
3648 int size = key.total_size;
3649 char* ctext = (char*)malloc(size);
3650
3652
3653 if (status != DB_SUCCESS) {
3654 char errtext[512];
3655 sprintf(errtext, "show_custom_file: Error: db_get_data() for \"%s\" status %d", str, status);
3657 free(ctext);
3658 return;
3659 }
3660
3661 filename = add_custom_path(ctext);
3662
3663 free(ctext);
3664
3665 send_file(r, filename, true);
3666
3667 return;
3668}
INT total_size
Definition midas.h:1031
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_gif()

void show_custom_gif ( Return rr,
const char name 
)

Definition at line 3672 of file mhttpd.cxx.

3673{
3674 char str[256], data[256], src[256];
3675 int i, index, length, status, size, width, height, bgcol, fgcol, bdcol, r, g, b, x, y;
3677 double fvalue, ratio;
3678 KEY key, vkey;
3679 gdImagePtr im;
3682 FILE *f;
3683 CGIF_LABEL label;
3684 CGIF_BAR bar;
3685
3687
3688 /* find image description in ODB */
3689 sprintf(str, "/Custom/Images/%s", name);
3690 db_find_key(hDB, 0, str, &hkeygif);
3691 if (!hkeygif) {
3692
3693 // If we don't have Images directory,
3694 // then just treat this like any other custom file.
3696 return;
3697 }
3698
3699 /* load background image */
3700 std::string filename;
3701 db_get_value_string(hDB, hkeygif, "Background", 0, &filename, FALSE);
3702
3703 std::string full_filename = add_custom_path(filename);
3704
3705 f = fopen(full_filename.c_str(), "rb");
3706 if (f == NULL) {
3707 sprintf(str, "show_custom_gif: Cannot open file \"%s\"", full_filename.c_str());
3709 return;
3710 }
3711
3713 fclose(f);
3714
3715 if (im == NULL) {
3716 sprintf(str, "show_custom_gif: File \"%s\" is not a GIF image", filename.c_str());
3718 return;
3719 }
3720
3722
3723 /*---- draw labels ----------------------------------------------*/
3724
3725 db_find_key(hDB, hkeygif, "Labels", &hkeyroot);
3726 if (hkeyroot) {
3727 for (index = 0;; index++) {
3729 if (!hkey)
3730 break;
3731 db_get_key(hDB, hkey, &key);
3732
3733 size = sizeof(label);
3734 status = db_get_record1(hDB, hkey, &label, &size, 0, strcomb1(cgif_label_str).c_str());
3735 if (status != DB_SUCCESS) {
3736 cm_msg(MERROR, "show_custom_gif", "Cannot open data record for label \"%s\"",
3737 key.name);
3738 continue;
3739 }
3740
3741 if (label.src[0] == 0) {
3742 cm_msg(MERROR, "show_custom_gif", "Empty Src key for label \"%s\"", key.name);
3743 continue;
3744 }
3745
3746 db_find_key(hDB, 0, label.src, &hkeyval);
3747 if (!hkeyval) {
3748 cm_msg(MERROR, "show_custom_gif", "Invalid Src key \"%s\" for label \"%s\"",
3749 label.src, key.name);
3750 continue;
3751 }
3752
3754 size = sizeof(data);
3755 status = db_get_value(hDB, 0, label.src, data, &size, vkey.type, FALSE);
3756
3757 std::string value;
3758
3759 if (label.format[0]) {
3760 if (vkey.type == TID_FLOAT)
3761 value = msprintf(label.format, *(((float *) data)));
3762 else if (vkey.type == TID_DOUBLE)
3763 value = msprintf(label.format, *(((double *) data)));
3764 else if (vkey.type == TID_INT)
3765 value = msprintf(label.format, *(((INT *) data)));
3766 else if (vkey.type == TID_BOOL) {
3767 if (strstr(label.format, "%c"))
3768 value = msprintf(label.format, *(((INT *) data)) ? 'y' : 'n');
3769 else
3770 value = msprintf(label.format, *(((INT *) data)));
3771 } else
3772 value = db_sprintf(data, size, 0, vkey.type);
3773 } else
3774 value = db_sprintf(data, size, 0, vkey.type);
3775
3776 sscanf(label.fgcolor, "%02x%02x%02x", &r, &g, &b);
3777 fgcol = gdImageColorAllocate(im, r, g, b);
3778 if (fgcol == -1)
3779 fgcol = gdImageColorClosest(im, r, g, b);
3780
3781 sscanf(label.bgcolor, "%02x%02x%02x", &r, &g, &b);
3782 bgcol = gdImageColorAllocate(im, r, g, b);
3783 if (bgcol == -1)
3784 bgcol = gdImageColorClosest(im, r, g, b);
3785
3786 /* select font */
3787 if (equal_ustring(label.font, "Small"))
3789 else if (equal_ustring(label.font, "Medium"))
3791 else if (equal_ustring(label.font, "Giant"))
3793 else
3795
3796 width = value.length() * pfont->w + 5 + 5;
3797 height = pfont->h + 2 + 2;
3798
3799 if (label.align == 0) {
3800 /* left */
3801 gdImageFilledRectangle(im, label.x, label.y, label.x + width,
3802 label.y + height, bgcol);
3803 gdImageRectangle(im, label.x, label.y, label.x + width, label.y + height,
3804 fgcol);
3805 gdImageString(im, pfont, label.x + 5, label.y + 2, value.c_str(), fgcol);
3806 } else if (label.align == 1) {
3807 /* center */
3808 gdImageFilledRectangle(im, label.x - width / 2, label.y, label.x + width / 2,
3809 label.y + height, bgcol);
3810 gdImageRectangle(im, label.x - width / 2, label.y, label.x + width / 2,
3811 label.y + height, fgcol);
3812 gdImageString(im, pfont, label.x + 5 - width / 2, label.y + 2, value.c_str(), fgcol);
3813 } else {
3814 /* right */
3815 gdImageFilledRectangle(im, label.x - width, label.y, label.x,
3816 label.y + height, bgcol);
3817 gdImageRectangle(im, label.x - width, label.y, label.x, label.y + height,
3818 fgcol);
3819 gdImageString(im, pfont, label.x - width + 5, label.y + 2, value.c_str(), fgcol);
3820 }
3821 }
3822 }
3823
3824 /*---- draw bars ------------------------------------------------*/
3825
3826 db_find_key(hDB, hkeygif, "Bars", &hkeyroot);
3827 if (hkeyroot) {
3828 for (index = 0;; index++) {
3830 if (!hkey)
3831 break;
3832 db_get_key(hDB, hkey, &key);
3833
3834 size = sizeof(bar);
3836 if (status != DB_SUCCESS) {
3837 cm_msg(MERROR, "show_custom_gif", "Cannot open data record for bar \"%s\"",
3838 key.name);
3839 continue;
3840 }
3841
3842 if (bar.src[0] == 0) {
3843 cm_msg(MERROR, "show_custom_gif", "Empty Src key for bar \"%s\"", key.name);
3844 continue;
3845 }
3846
3847 db_find_key(hDB, 0, bar.src, &hkeyval);
3848 if (!hkeyval) {
3849 cm_msg(MERROR, "show_custom_gif", "Invalid Src key \"%s\" for bar \"%s\"",
3850 bar.src, key.name);
3851 continue;
3852 }
3853
3855 size = sizeof(data);
3856 status = db_get_value(hDB, 0, bar.src, data, &size, vkey.type, FALSE);
3857 std::string value = db_sprintf(data, size, 0, vkey.type);
3858 if (equal_ustring(value.c_str(), "NAN"))
3859 continue;
3860
3861 fvalue = atof(value.c_str());
3862
3863 sscanf(bar.fgcolor, "%02x%02x%02x", &r, &g, &b);
3864 fgcol = gdImageColorAllocate(im, r, g, b);
3865 if (fgcol == -1)
3866 fgcol = gdImageColorClosest(im, r, g, b);
3867
3868 sscanf(bar.bgcolor, "%02x%02x%02x", &r, &g, &b);
3869 bgcol = gdImageColorAllocate(im, r, g, b);
3870 if (bgcol == -1)
3871 bgcol = gdImageColorClosest(im, r, g, b);
3872
3873 sscanf(bar.bdcolor, "%02x%02x%02x", &r, &g, &b);
3874 bdcol = gdImageColorAllocate(im, r, g, b);
3875 if (bdcol == -1)
3876 bdcol = gdImageColorClosest(im, r, g, b);
3877
3878 if (bar.min == bar.max)
3879 bar.max += 1;
3880
3881 if (bar.logscale) {
3882 if (fvalue < 1E-20)
3883 fvalue = 1E-20;
3884 ratio = (log(fvalue) - log(bar.min)) / (log(bar.max) - log(bar.min));
3885 } else
3886 ratio = (fvalue - bar.min) / (bar.max - bar.min);
3887 if (ratio < 0)
3888 ratio = 0;
3889 if (ratio > 1)
3890 ratio = 1;
3891
3892 if (bar.direction == 0) {
3893 /* vertical */
3894 ratio = (bar.height - 2) - ratio * (bar.height - 2);
3895 r = (int) (ratio + 0.5);
3896
3897 gdImageFilledRectangle(im, bar.x, bar.y, bar.x + bar.width,
3898 bar.y + bar.height, bgcol);
3899 gdImageRectangle(im, bar.x, bar.y, bar.x + bar.width, bar.y + bar.height,
3900 bdcol);
3901 gdImageFilledRectangle(im, bar.x + 1, bar.y + r + 1, bar.x + bar.width - 1,
3902 bar.y + bar.height - 1, fgcol);
3903
3904 if (bar.axis == 1)
3905 vaxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y + bar.height, bar.height, -3,
3906 -5, -7, -8, 0, bar.min, bar.max, bar.logscale);
3907 else if (bar.axis == 2)
3908 vaxis(im, gdFontSmall, bdcol, 0, bar.x + bar.width, bar.y + bar.height,
3909 bar.height, 3, 5, 7, 10, 0, bar.min, bar.max, bar.logscale);
3910
3911 } else {
3912 /* horizontal */
3913 ratio = ratio * (bar.height - 2);
3914 r = (int) (ratio + 0.5);
3915
3916 gdImageFilledRectangle(im, bar.x, bar.y, bar.x + bar.height,
3917 bar.y + bar.width, bgcol);
3918 gdImageRectangle(im, bar.x, bar.y, bar.x + bar.height, bar.y + bar.width,
3919 bdcol);
3920 gdImageFilledRectangle(im, bar.x + 1, bar.y + 1, bar.x + r,
3921 bar.y + bar.width - 1, fgcol);
3922
3923 if (bar.axis == 1)
3924 haxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y, bar.height, -3, -5, -7, -18,
3925 0, bar.min, bar.max);
3926 else if (bar.axis == 2)
3927 haxis(im, gdFontSmall, bdcol, 0, bar.x, bar.y + bar.width, bar.height, 3,
3928 5, 7, 8, 0, bar.min, bar.max);
3929 }
3930 }
3931 }
3932
3933 /*---- draw fills -----------------------------------------------*/
3934
3935 db_find_key(hDB, hkeygif, "Fills", &hkeyroot);
3936 if (hkeyroot) {
3937 for (index = 0;; index++) {
3939 if (!hkey)
3940 break;
3941 db_get_key(hDB, hkey, &key);
3942
3943 size = sizeof(src);
3944 src[0] = 0;
3945 db_get_value(hDB, hkey, "Src", src, &size, TID_STRING, TRUE);
3946
3947 if (src[0] == 0) {
3948 cm_msg(MERROR, "show_custom_gif", "Empty Src key for Fill \"%s\"", key.name);
3949 continue;
3950 }
3951
3952 if (!evaluate_src(key.name, src, &fvalue))
3953 continue;
3954
3955 x = y = 0;
3956 size = sizeof(x);
3957 db_get_value(hDB, hkey, "X", &x, &size, TID_INT, TRUE);
3958 db_get_value(hDB, hkey, "Y", &y, &size, TID_INT, TRUE);
3959
3960 size = sizeof(data);
3961 status = db_get_value(hDB, hkey, "Limits", data, &size, TID_DOUBLE, FALSE);
3962 if (status != DB_SUCCESS) {
3963 cm_msg(MERROR, "show_custom_gif", "No \"Limits\" entry for Fill \"%s\"",
3964 key.name);
3965 continue;
3966 }
3967 for (i = 0; i < size / (int) sizeof(double); i++)
3968 if (*((double *) data + i) > fvalue)
3969 break;
3970 if (i > 0)
3971 i--;
3972
3973 db_find_key(hDB, hkey, "Fillcolors", &hkeyval);
3974 if (!hkeyval) {
3975 cm_msg(MERROR, "show_custom_gif", "No \"Fillcolors\" entry for Fill \"%s\"",
3976 key.name);
3977 continue;
3978 }
3979
3980 size = sizeof(data);
3981 strcpy(data, "FFFFFF");
3983 if (status == DB_SUCCESS) {
3984 sscanf(data, "%02x%02x%02x", &r, &g, &b);
3985 fgcol = gdImageColorAllocate(im, r, g, b);
3986 if (fgcol == -1)
3987 fgcol = gdImageColorClosest(im, r, g, b);
3988 gdImageFill(im, x, y, fgcol);
3989 }
3990 }
3991 }
3992
3993 /* generate GIF */
3994 gdImageInterlace(im, 1);
3995 gdImageGif(im, &gb);
3997 length = gb.size;
3998
3999 rr->rsprintf("HTTP/1.1 200 Document follows\r\n");
4000 rr->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
4001
4002 rr->rsprintf("Content-Type: image/gif\r\n");
4003 rr->rsprintf("Content-Length: %d\r\n", length);
4004 rr->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
4005 rr->rsprintf("Expires: Fri, 01-Jan-1983 00:00:00 GMT\r\n\r\n");
4006
4007 rr->rmemcpy(gb.data, length);
4008}
#define TID_DOUBLE
Definition midas.h:343
#define TID_FLOAT
Definition midas.h:341
gdImagePtr gdImageCreateFromGif(FILE *fd)
Definition mgd.cxx:1888
int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
Definition mgd.cxx:455
void gdImageFill(gdImagePtr im, int x, int y, int color)
Definition mgd.cxx:964
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
Definition odb.cxx:11805
void haxis(gdImagePtr im, gdFont *font, int col, int gcol, int x1, int y1, int width, int minor, int major, int text, int label, int grid, double xmin, double xmax)
Definition mhttpd.cxx:7632
void show_custom_file(Return *r, const char *name)
Definition mhttpd.cxx:3609
int evaluate_src(char *key, char *src, double *fvalue)
Definition mhttpd.cxx:3497
static const char * cgif_bar_str[]
Definition mhttpd.cxx:3468
static const char * cgif_label_str[]
Definition mhttpd.cxx:3428
char format[32]
Definition mhttpd.cxx:3442
char src[256]
Definition mhttpd.cxx:3441
char bgcolor[8]
Definition mhttpd.cxx:3446
char font[32]
Definition mhttpd.cxx:3443
char fgcolor[8]
Definition mhttpd.cxx:3445
Definition mgd.h:58
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_custom_page()

void show_custom_page ( Param pp,
Return r,
const char cookie_cpwd 
)

Definition at line 5419 of file mhttpd.cxx.

5420{
5421 int size, n_var, index, edit;
5422 char keypath[256], type[32], *p, *ps;
5423 char pwd[256], tail[256];
5424 HNDLE hDB, hkey;
5425 KEY key;
5426 char data[TEXT_SIZE];
5427
5428 std::string path = pp->getparam("page");
5429
5430 if (path[0] == 0) {
5431 show_error_404(r, "show_custom_page: Invalid custom page: \"page\" parameter is empty");
5432 return;
5433 }
5434
5435 if (strstr(path.c_str(), "..")) {
5436 std::string str;
5437 str += "Invalid custom page name \'";
5438 str += path;
5439 str += "\' contains \'..\'";
5440 show_error_404(r, str.c_str());
5441 return;
5442 }
5443
5444 if (strstr(path.c_str(), ".gif")) {
5445 show_custom_gif(r, path.c_str());
5446 return;
5447 }
5448
5449 if (strchr(path.c_str(), '.')) {
5450 show_custom_file(r, path.c_str());
5451 return;
5452 }
5453
5455
5456 std::string xpath = std::string("/Custom/") + path;
5457 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5458 if (!hkey) {
5459 xpath = std::string("/Custom/") + path + "&";
5460 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5461 if (!hkey) {
5462 xpath = std::string("/Custom/") + path + "!";
5463 db_find_key(hDB, 0, xpath.c_str(), &hkey);
5464 }
5465 }
5466
5467 if (hkey) {
5468 char* ctext;
5469 int status;
5470
5472 assert(status == DB_SUCCESS);
5473 size = key.total_size;
5474 ctext = (char*)malloc(size);
5476 if (status != DB_SUCCESS) {
5477 std::string errtext = msprintf("show_custom_page: Error: db_get_data() for \"%s\" status %d", xpath.c_str(), status);
5478 show_error_404(r, errtext.c_str());
5479 free(ctext);
5480 return;
5481 }
5482
5483 std::string content_type = "text/html";
5484
5485 /* check for link */
5486 if (std::string(ctext).substr(0, 5) == "?cmd=") {
5487 redirect(r, ctext);
5488 free(ctext);
5489 return;
5490 }
5491
5492 /* check if filename */
5493 if (strchr(ctext, '\n') == 0) {
5494 std::string full_filename = add_custom_path(ctext);
5495 int fh = open(full_filename.c_str(), O_RDONLY | O_BINARY);
5496 if (fh < 0) {
5497 std::string str = msprintf("show_custom_page: Cannot open file \"%s\", open() errno %d (%s)", full_filename.c_str(), errno, strerror(errno));
5498 show_error_404(r, str.c_str());
5499 free(ctext);
5500 return;
5501 }
5502 free(ctext);
5503 ctext = NULL;
5504 off_t off = lseek(fh, 0, SEEK_END);
5505 if (off < 0) {
5506 std::string str = msprintf("show_custom_page: Cannot open file \"%s\", lseek(SEEK_END) errno %d (%s)", full_filename.c_str(), errno, strerror(errno));
5507 show_error_404(r, str.c_str());
5508 free(ctext);
5509 close(fh);
5510 return;
5511 }
5512 size_t size = off;
5513 lseek(fh, 0, SEEK_SET);
5514 ctext = (char*)malloc(size+1);
5515 ssize_t rd = read(fh, ctext, size);
5516 if (rd > 0) {
5517 ctext[rd] = 0; // make sure string is zero-terminated
5518 size = rd;
5519 } else {
5520 ctext[0] = 0;
5521 size = 0;
5522 }
5523 close(fh);
5524
5526 }
5527
5528 /* check for valid password */
5529 if (equal_ustring(pp->getparam("cmd"), "Edit")) {
5530 p = ps = ctext;
5531 n_var = 0;
5532 do {
5533 char format[256];
5534
5535 p = find_odb_tag(ps, keypath, format, &edit, type, pwd, tail);
5536 if (p == NULL)
5537 break;
5538 ps = strchr(p, '>') + 1;
5539
5540 if (pwd[0] && n_var == atoi(pp->getparam("index"))) {
5541 char str[256];
5542 size = NAME_LENGTH;
5543 mstrlcpy(str, path.c_str(), sizeof(str)); // FIXME: overflows "str"
5544 if (strlen(str)>0 && str[strlen(str)-1] == '&')
5545 str[strlen(str)-1] = 0;
5546 std::string ppath;
5547 ppath += "/Custom/Pwd/";
5548 if (pp->getparam("pnam") && *pp->getparam("pnam")) {
5549 ppath += pp->getparam("pnam");
5550 } else {
5551 ppath += str;
5552 }
5553 str[0] = 0;
5554 db_get_value(hDB, 0, ppath.c_str(), str, &size, TID_STRING, TRUE);
5555 if (!equal_ustring(cookie_cpwd, str)) {
5556 show_error_404(r, "show_custom_page: Invalid password!");
5557 free(ctext);
5558 return;
5559 } else
5560 break;
5561 }
5562
5563 n_var++;
5564 } while (p != NULL);
5565 }
5566
5567 /* process toggle command */
5568 if (equal_ustring(pp->getparam("cmd"), "Toggle")) {
5569
5570 if (pp->getparam("pnam") && *pp->getparam("pnam")) {
5571 std::string ppath;
5572 ppath += "/Custom/Pwd/";
5573 ppath += pp->getparam("pnam");
5574 std::string str;
5575 db_get_value_string(hDB, 0, ppath.c_str(), 0, &str, TRUE, 256);
5576 if (!equal_ustring(cookie_cpwd, str.c_str())) {
5577 show_error_404(r, "show_custom_page: Invalid password!");
5578 free(ctext);
5579 return;
5580 }
5581 }
5582 std::string podb = pp->getparam("odb");
5583 std::string::size_type pos = podb.find('[');
5584 if (pos != std::string::npos) {
5585 index = atoi(podb.substr(pos+1).c_str());
5586 podb.resize(pos);
5587 //printf("found index %d in [%s] [%s]\n", index, pp->getparam("odb"), podb.c_str());
5588 } else
5589 index = 0;
5590
5591 if (db_find_key(hDB, 0, podb.c_str(), &hkey)) {
5592 db_get_key(hDB, hkey, &key);
5593 memset(data, 0, sizeof(data));
5594 if (key.item_size <= (int)sizeof(data)) {
5595 size = sizeof(data);
5597 std::string data_str = db_sprintf(data, size, 0, key.type);
5598 if (atoi(data_str.c_str()) == 0)
5599 db_sscanf("1", data, &size, 0, key.type);
5600 else
5601 db_sscanf("0", data, &size, 0, key.type);
5603 }
5604 }
5605
5606 /* redirect (so that 'reload' does not toggle again) */
5607 redirect(r, path.c_str());
5608 free(ctext);
5609 return;
5610 }
5611
5612 /* HTTP header */
5613 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
5614 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
5615 r->rsprintf("Content-Type: %s; charset=%s\r\n\r\n", content_type.c_str(), HTTP_ENCODING);
5616
5617 /* interprete text, replace <odb> tags with ODB values */
5618 p = ps = ctext;
5619 n_var = 0;
5620 do {
5621 char format[256];
5622 p = find_odb_tag(ps, keypath, format, &edit, type, pwd, tail);
5623 if (p != NULL)
5624 *p = 0;
5625 r->rsputs(ps);
5626
5627 if (p == NULL)
5628 break;
5629 ps = strchr(p + 1, '>') + 1;
5630
5631 show_odb_tag(pp, r, path.c_str(), keypath, format, n_var, edit, type, pwd, tail);
5632 n_var++;
5633
5634 } while (p != NULL);
5635
5636 if (equal_ustring(pp->getparam("cmd"), "Set") || pp->isparam("cbi")) {
5637 /* redirect (so that 'reload' does not change value) */
5638 r->reset();
5639 redirect(r, path.c_str());
5640 }
5641
5642 free(ctext);
5643 ctext = NULL;
5644 } else {
5645 std::string str = msprintf("Invalid custom page: Page \"%s\" not found in ODB", path.c_str());
5646 show_error_404(r, str.c_str());
5647 return;
5648 }
5649}
void reset()
Definition mhttpd.cxx:542
#define O_BINARY
Definition msystem.h:219
char * find_odb_tag(char *p, char *path, char *format, int *edit, char *type, char *pwd, char *tail)
Definition mhttpd.cxx:3091
void show_odb_tag(Param *pp, Return *r, const char *path, const char *keypath1, const char *format, int n_var, int edit, char *type, char *pwd, char *tail)
Definition mhttpd.cxx:3275
#define read(n, a, f)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_elog_attachment()

void show_elog_attachment ( Param p,
Return r,
const char path 
)

Definition at line 2483 of file mhttpd.cxx.

2484{
2485 HNDLE hDB;
2486 int size;
2487 int status;
2488 char file_name[256];
2489
2491 file_name[0] = 0;
2492 if (hDB > 0) {
2493 size = sizeof(file_name);
2494 memset(file_name, 0, size);
2495
2496 status = db_get_value(hDB, 0, "/Logger/Elog dir", file_name, &size, TID_STRING, FALSE);
2497 if (status != DB_SUCCESS)
2498 db_get_value(hDB, 0, "/Logger/Data dir", file_name, &size, TID_STRING, TRUE);
2499
2500 if (file_name[0] != 0)
2503 }
2504 mstrlcat(file_name, path, sizeof(file_name));
2505
2506 int fh = open(file_name, O_RDONLY | O_BINARY);
2507 if (fh > 0) {
2508 lseek(fh, 0, SEEK_END);
2509 int length = TELL(fh);
2510 lseek(fh, 0, SEEK_SET);
2511
2512 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2513 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2514 r->rsprintf("Accept-Ranges: bytes\r\n");
2515 //r->rsprintf("Content-disposition: attachment; filename=%s\r\n", path);
2516
2517 r->rsprintf("Content-Type: %s\r\n", get_content_type(file_name).c_str());
2518
2519 r->rsprintf("Content-Length: %d\r\n\r\n", length);
2520
2521 r->rread(file_name, fh, length);
2522
2523 close(fh);
2524 }
2525
2526 return;
2527}
#define TELL(fh)
Definition msystem.h:243
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_eqtable_page()

void show_eqtable_page ( Param pp,
Return r,
int  refresh 
)

Definition at line 2558 of file mhttpd.cxx.

2559{
2560 int i, j, k, colspan, size, n_var, i_edit, i_set, line;
2561 char eq_name[32], group[32];
2562 char group_name[MAX_GROUPS][32], data[256], style[80];
2563 HNDLE hDB;
2564 char odb_path[256];
2565
2567
2568 /* check if variable to edit */
2569 i_edit = -1;
2570 if (equal_ustring(pp->getparam("cmd"), "Edit"))
2571 i_edit = atoi(pp->getparam("index"));
2572
2573 /* check if variable to set */
2574 i_set = -1;
2575 if (equal_ustring(pp->getparam("cmd"), "Set"))
2576 i_set = atoi(pp->getparam("index"));
2577
2578 /* get equipment and group */
2579 if (pp->getparam("eq"))
2580 mstrlcpy(eq_name, pp->getparam("eq"), sizeof(eq_name));
2581 mstrlcpy(group, "All", sizeof(group));
2582 if (pp->getparam("group") && *pp->getparam("group"))
2583 mstrlcpy(group, pp->getparam("group"), sizeof(group));
2584
2585#if 0
2586 /* check for "names" in settings */
2587 if (eq_name[0]) {
2588 sprintf(str, "/Equipment/%s/Settings", eq_name);
2589 HNDLE hkeyset;
2590 db_find_key(hDB, 0, str, &hkeyset);
2591 HNDLE hkeynames = 0;
2592 if (hkeyset) {
2593 for (i = 0;; i++) {
2595
2596 if (!hkeynames)
2597 break;
2598
2599 KEY key;
2601
2602 if (strncmp(key.name, "Names", 5) == 0)
2603 break;
2604 }
2605 }
2606
2607 /* redirect if no names found */
2608 if (!hkeyset || !hkeynames) {
2609 /* redirect */
2610 sprintf(str, "?cmd=odb&odb_path=/Equipment/%s/Variables", eq_name);
2611 redirect(r, str);
2612 return;
2613 }
2614 }
2615#endif
2616
2617 show_header(r, "MIDAS slow control", "", group, i_edit == -1 ? refresh : 0);
2618 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
2619 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
2620 r->rsprintf("<script type=\"text/javascript\" src=\"obsolete.js\"></script>\n");
2621 show_navigation_bar(r, "SC");
2622
2623 /*---- menu buttons ----*/
2624
2625 r->rsprintf("<tr><td colspan=15>\n");
2626
2627 if (equal_ustring(pp->getparam("cmd"), "Edit"))
2628 r->rsprintf("<input type=submit name=cmd value=Set>\n");
2629
2630 r->rsprintf("</tr>\n\n");
2631 r->rsprintf("</table>"); //end header table
2632
2633 r->rsprintf("<table class=\"ODBtable\" style=\"max-width:700px;\">"); //body table
2634
2635 /*---- enumerate SC equipment ----*/
2636
2637 r->rsprintf("<tr><td class=\"subStatusTitle\" colspan=15><i>Equipment:</i> &nbsp;&nbsp;\n");
2638
2640 db_find_key(hDB, 0, "/Equipment", &hkeyeqroot);
2641 if (hkeyeqroot)
2642 for (i = 0;; i++) {
2643 HNDLE hkeyeq;
2645
2646 if (!hkeyeq)
2647 break;
2648
2649 KEY eqkey;
2651
2652 HNDLE hkeyset;
2653 db_find_key(hDB, hkeyeq, "Settings", &hkeyset);
2654 if (hkeyset) {
2655 for (j = 0;; j++) {
2658
2659 if (!hkeynames)
2660 break;
2661
2662 KEY key;
2664
2665 if (strncmp(key.name, "Names", 5) == 0) {
2666 if (equal_ustring(eq_name, eqkey.name))
2667 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", eqkey.name);
2668 else {
2669 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eqkey.name).c_str(), eqkey.name);
2670 }
2671 break;
2672 }
2673 }
2674 }
2675 }
2676 r->rsprintf("</tr>\n");
2677
2678 if (!eq_name[0]) {
2679 r->rsprintf("</table>");
2680 return;
2681 }
2682
2683 /*---- display SC ----*/
2684
2685 n_var = 0;
2686 std::string names_path = msprintf("/Equipment/%s/Settings/Names", eq_name);
2688 db_find_key(hDB, 0, names_path.c_str(), &hkeyeqnames);
2689
2690 if (hkeyeqnames) {
2691
2692 /*---- single name array ----*/
2693 r->rsprintf("<tr><td colspan=15><i>Groups:</i> &nbsp;&nbsp;");
2694
2695 /* "all" group */
2696 if (equal_ustring(group, "All"))
2697 r->rsprintf("<b>All</b> &nbsp;&nbsp;");
2698 else
2699 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">All</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2700
2701 /* collect groups */
2702
2703 memset(group_name, 0, sizeof(group_name));
2704 KEY key;
2706
2707 for (int level = 0; ; level++) {
2708 bool next_level = false;
2709 for (i = 0; i < key.num_values; i++) {
2710 char name_str[256];
2711 size = sizeof(name_str);
2713
2714 char *s = strchr(name_str, '%');
2715 for (int k=0; s && k<level; k++)
2716 s = strchr(s+1, '%');
2717
2718 if (s) {
2719 *s = 0;
2720 if (strchr(s+1, '%'))
2721 next_level = true;
2722
2723 //printf("try group [%s] name [%s], level %d, %d\n", name_str, s+1, level, next_level);
2724
2725 for (j = 0; j < MAX_GROUPS; j++) {
2726 if (equal_ustring(group_name[j], name_str) || group_name[j][0] == 0)
2727 break;
2728 }
2729 if (group_name[j][0] == 0)
2730 mstrlcpy(group_name[j], name_str, sizeof(group_name[0]));
2731 }
2732 }
2733
2734 if (!next_level)
2735 break;
2736 }
2737
2738 for (i = 0; i < MAX_GROUPS && group_name[i][0]; i++) {
2740 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", group_name[i]);
2741 else {
2742 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s&group=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str(), urlEncode(group_name[i]).c_str(), group_name[i]);
2743 }
2744 }
2745
2746 r->rsprintf("<i>ODB:</i> &nbsp;&nbsp;");
2747 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Common\">Common</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2748 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Settings\">Settings</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2749 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Variables\">Variables</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2750 r->rsprintf("</tr>\n");
2751
2752 /* count variables */
2753 std::string vars_path = msprintf("/Equipment/%s/Variables", eq_name);
2754 HNDLE hkeyvar;
2755 db_find_key(hDB, 0, vars_path.c_str(), &hkeyvar);
2756 if (!hkeyvar) {
2757 r->rsprintf("</table>");
2758 return;
2759 }
2760 for (i = 0;; i++) {
2761 HNDLE hkey;
2763 if (!hkey)
2764 break;
2765 }
2766
2767 if (i == 0 || i > 15) {
2768 r->rsprintf("</table>");
2769 return;
2770 }
2771
2772 /* title row */
2773 colspan = 15 - i;
2774 r->rsprintf("<tr class=\"subStatusTitle\"><th colspan=%d>Names", colspan);
2775
2776 /* display entries for this group */
2777 for (int i = 0;; i++) {
2778 HNDLE hkey;
2780
2781 if (!hkey)
2782 break;
2783
2784 KEY key;
2785 db_get_key(hDB, hkey, &key);
2786 r->rsprintf("<th>%s", key.name);
2787 }
2788
2789 r->rsprintf("</tr>\n");
2790
2791 /* data for current group */
2792 std::string names_path = msprintf("/Equipment/%s/Settings/Names", eq_name);
2793 int num_values = 0;
2795 db_find_key(hDB, 0, names_path.c_str(), &hnames_key);
2796 if (hnames_key) {
2797 KEY names_key;
2799 num_values = names_key.num_values;
2800 }
2801 for (int i = 0; i < num_values; i++) {
2802 char names_str[256];
2803 size = sizeof(names_str);
2805
2806 char name[NAME_LENGTH+32];
2807 mstrlcpy(name, names_str, sizeof(name));
2808
2809 //printf("group [%s], name [%s], str [%s]\n", group, name, names_str);
2810
2811 if (!equal_ustring(group, "All")) {
2812 // check if name starts with the name of the group we want to display
2813 char *s = strstr(name, group);
2814 if (s != name)
2815 continue;
2816 if (name[strlen(group)] != '%')
2817 continue;
2818 }
2819
2820 if (strlen(name) < 1)
2821 sprintf(name, "[%d]", i);
2822
2823 if (i % 2 == 0)
2824 r->rsprintf("<tr class=\"ODBtableEven\"><td colspan=%d><nobr>%s</nobr>", colspan, name);
2825 else
2826 r->rsprintf("<tr class=\"ODBtableOdd\"><td colspan=%d><nobr>%s</nobr>", colspan, name);
2827
2828 for (int j = 0;; j++) {
2829 HNDLE hkey;
2831 if (!hkey)
2832 break;
2833
2834 KEY varkey;
2836
2837 /* check if "variables" array is shorter than the "names" array */
2838 if (i >= varkey.num_values)
2839 continue;
2840
2841 size = sizeof(data);
2842 db_get_data_index(hDB, hkey, data, &size, i, varkey.type);
2843 std::string data_str = db_sprintf(data, varkey.item_size, 0, varkey.type);
2844
2845 if (is_editable(eq_name, varkey.name)) {
2846 if (n_var == i_set) {
2847 /* set value */
2848 char str[256];
2849 mstrlcpy(str, pp->getparam("value"), sizeof(str));
2850 db_sscanf(str, data, &size, 0, varkey.type);
2851 db_set_data_index(hDB, hkey, data, size, i, varkey.type);
2852
2853 /* redirect (so that 'reload' does not reset value) */
2854 r->reset();
2855 redirect(r, group);
2856 return;
2857 }
2858 if (n_var == i_edit) {
2859 r->rsprintf("<td align=center>");
2860 r->rsprintf("<input type=text size=10 maxlenth=80 name=value value=\"%s\">\n", data_str.c_str());
2861 r->rsprintf("<input type=submit size=20 name=cmd value=Set>\n");
2862 r->rsprintf("<input type=hidden name=index value=%d>\n", i_edit);
2863 n_var++;
2864 } else {
2865 sprintf(odb_path, "Equipment/%s/Variables/%s[%d]", eq_name, varkey.name, i);
2866 r->rsprintf("<td align=center>");
2867 r->rsprintf("<a href=\"#\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\', 0);return false;\" >%s</a>", odb_path, data_str.c_str());
2868 n_var++;
2869 }
2870 } else
2871 r->rsprintf("<td align=center>%s", data_str.c_str());
2872 }
2873
2874 r->rsprintf("</tr>\n");
2875 }
2876 } else {
2877 /*---- multiple name arrays ----*/
2878 r->rsprintf("<tr><td colspan=15><i>Groups:</i> ");
2879
2880 /* "all" group */
2881 if (equal_ustring(group, "All"))
2882 r->rsprintf("<b>All</b> &nbsp;&nbsp;");
2883 else
2884 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s\">All</a> &nbsp;&nbsp;", eq_name);
2885
2886 /* groups from Variables tree */
2887
2888 std::string vars_path = msprintf("/Equipment/%s/Variables", eq_name);
2889 HNDLE hkeyvar;
2890 db_find_key(hDB, 0, vars_path.c_str(), &hkeyvar);
2891
2892 if (hkeyvar) {
2893 for (int i = 0;; i++) {
2894 HNDLE hkey;
2896
2897 if (!hkey)
2898 break;
2899
2900 KEY key;
2901 db_get_key(hDB, hkey, &key);
2902
2903 if (equal_ustring(key.name, group)) {
2904 r->rsprintf("<b>%s</b> &nbsp;&nbsp;", key.name);
2905 } else {
2906 r->rsprintf("<a href=\"?cmd=eqtable&eq=%s&group=%s\">%s</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str(), urlEncode(key.name).c_str(), key.name);
2907 }
2908 }
2909 }
2910
2911 r->rsprintf("<i>ODB:</i> &nbsp;&nbsp;");
2912 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Common\">Common</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2913 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Settings\">Settings</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2914 r->rsprintf("<a href=\"?cmd=odb&odb_path=Equipment/%s/Variables\">Variables</a> &nbsp;&nbsp;", urlEncode(eq_name).c_str());
2915 r->rsprintf("</tr>\n");
2916
2917 /* enumerate variable arrays */
2918 line = 0;
2919 for (i = 0;; i++) {
2920 HNDLE hkey;
2922
2923 if (line % 2 == 0)
2924 mstrlcpy(style, "ODBtableEven", sizeof(style));
2925 else
2926 mstrlcpy(style, "ODBtableOdd", sizeof(style));
2927
2928 if (!hkey)
2929 break;
2930
2931 KEY varkey;
2933
2934 if (!equal_ustring(group, "All") && !equal_ustring(varkey.name, group))
2935 continue;
2936
2937 /* title row */
2938 r->rsprintf("<tr class=\"subStatusTitle\"><th colspan=9>Names<th>%s</tr>\n", varkey.name);
2939
2940 if (varkey.type == TID_KEY) {
2942
2943 /* enumerate subkeys */
2944 for (j = 0;; j++) {
2946 if (!hkey)
2947 break;
2948
2949 KEY key;
2950 db_get_key(hDB, hkey, &key);
2951
2952 if (key.type == TID_KEY) {
2953 /* for keys, don't display data value */
2954 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<br></tr>\n", style, key.name);
2955 } else {
2956 /* display single value */
2957 if (key.num_values == 1) {
2958 size = sizeof(data);
2959 db_get_data(hDB, hkey, data, &size, key.type);
2960
2961 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2962 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2963
2964 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2965 data_str = "(empty)";
2966 hex_str = "";
2967 }
2968
2969 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
2970 r->rsprintf
2971 ("<tr class=\"%s\" ><td colspan=9>%s<td align=center>%s (%s)<br></tr>\n",
2972 style, key.name, data_str.c_str(), hex_str.c_str());
2973 else
2974 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<td align=center>%s<br></tr>\n",
2975 style, key.name, data_str.c_str());
2976 line++;
2977 } else {
2978 /* display first value */
2979 r->rsprintf("<tr class=\"%s\"><td colspan=9 rowspan=%d>%s\n", style, key.num_values,
2980 key.name);
2981
2982 for (k = 0; k < key.num_values; k++) {
2983 size = sizeof(data);
2984 db_get_data_index(hDB, hkey, data, &size, k, key.type);
2985 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2986 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2987
2988 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2989 data_str = "(empty)";
2990 hex_str = "";
2991 }
2992
2993 if (k > 0)
2994 r->rsprintf("<tr>");
2995
2996 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
2997 r->rsprintf("<td>[%d] %s (%s)<br></tr>\n", k, data_str.c_str(), hex_str.c_str());
2998 else
2999 r->rsprintf("<td>[%d] %s<br></tr>\n", k, data_str.c_str());
3000 line++;
3001 }
3002 }
3003 }
3004 }
3005 } else {
3006 /* data for current group */
3007 std::string names_path = msprintf("/Equipment/%s/Settings/Names %s", eq_name, varkey.name);
3008 HNDLE hkeyset;
3009 db_find_key(hDB, 0, names_path.c_str(), &hkeyset);
3010 KEY key;
3011 if (hkeyset)
3013
3014 if (varkey.num_values > 1000)
3015 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s<td align=center><i>... %d values ...</i>",
3016 style, varkey.name, varkey.num_values);
3017 else {
3018 for (j = 0; j < varkey.num_values; j++) {
3019
3020 if (line % 2 == 0)
3021 mstrlcpy(style, "ODBtableEven", sizeof(style));
3022 else
3023 mstrlcpy(style, "ODBtableOdd", sizeof(style));
3024
3025 char name[NAME_LENGTH+32];
3026 if (hkeyset && j<key.num_values) {
3027 size = sizeof(name);
3029 } else {
3030 sprintf(name, "%s[%d]", varkey.name, j);
3031 }
3032
3033 if (strlen(name) < 1) {
3034 sprintf(name, "%s[%d]", varkey.name, j);
3035 }
3036
3037 r->rsprintf("<tr class=\"%s\"><td colspan=9>%s", style, name);
3038
3039 size = sizeof(data);
3040 db_get_data_index(hDB, hkey, data, &size, j, varkey.type);
3041 std::string data_str = db_sprintf(data, varkey.item_size, 0, varkey.type);
3042
3043 if (is_editable(eq_name, varkey.name)) {
3044 if (n_var == i_set) {
3045 /* set value */
3046 char str[256];
3047 mstrlcpy(str, pp->getparam("value"), sizeof(str));
3048 db_sscanf(str, data, &size, 0, varkey.type);
3049 db_set_data_index(hDB, hkey, data, size, j, varkey.type);
3050
3051 /* redirect (so that 'reload' does not reset value) */
3052 r->reset();
3053 sprintf(str, "%s", group);
3054 redirect(r, str);
3055 return;
3056 }
3057 if (n_var == i_edit) {
3058 r->rsprintf("<td align=center><input type=text size=10 maxlenth=80 name=value value=\"%s\">\n", data_str.c_str());
3059 r->rsprintf("<input type=submit size=20 name=cmd value=Set></tr>\n");
3060 r->rsprintf("<input type=hidden name=index value=%d>\n", i_edit);
3061 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
3062 n_var++;
3063 } else {
3064 sprintf(odb_path, "Equipment/%s/Variables/%s[%d]", eq_name, varkey.name, j);
3065
3066 r->rsprintf("<td align=cernter>");
3067 r->rsprintf("<a href=\"#\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\', 0);return false;\" >%s</a>", odb_path, data_str.c_str());
3068 n_var++;
3069 }
3070
3071 } else
3072 r->rsprintf("<td align=center>%s\n", data_str.c_str());
3073 r->rsprintf("</tr>\n");
3074 line++;
3075 }
3076 }
3077
3078 r->rsprintf("</tr>\n");
3079 }
3080 }
3081 }
3082
3083 r->rsprintf("</table>\n");
3084 r->rsprintf("</div>\n"); // closing for <div id="mmain">
3085 r->rsprintf("</form>\n");
3086 r->rsprintf("</body></html>\r\n");
3087}
BOOL is_editable(char *eq_name, char *var_name)
Definition mhttpd.cxx:2531
#define MAX_GROUPS
Definition mhttpd.cxx:50
void show_navigation_bar(Return *r, const char *cur_page)
Definition mhttpd.cxx:1867
void show_header(Return *r, const char *title, const char *method, const char *path, int refresh)
Definition mhttpd.cxx:1779
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_error()

void show_error ( Return r,
const char error 
)

Definition at line 1839 of file mhttpd.cxx.

1840{
1841 /* header */
1842 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1843 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1844 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1845
1846 r->rsprintf("<html><head>\n");
1847 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1848 r->rsprintf("<title>MIDAS error</title></head>\n");
1849 r->rsprintf("<body><H1>%s</H1></body></html>\n", error);
1850}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_error_404()

void show_error_404 ( Return r,
const char error 
)

Definition at line 1854 of file mhttpd.cxx.

1855{
1856 /* header */
1857 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1858 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1859 r->rsprintf("Content-Type: text/plain\r\n");
1860 r->rsprintf("\r\n");
1861
1862 r->rsprintf("MIDAS error: %s\n", error);
1863}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_find_page()

void show_find_page ( Return r,
const char value 
)

Definition at line 7567 of file mhttpd.cxx.

7568{
7569 HNDLE hDB, hkey;
7570
7572
7573 if (value[0] == 0) {
7574 /* without value, show find dialog */
7575 show_header(r, "Find value", "GET", "", 0);
7576
7577 //end header:
7578 r->rsprintf("</table>");
7579
7580 //find dialog:
7581 r->rsprintf("<table class=\"dialogTable\">");
7582
7583 r->rsprintf("<tr><th colspan=2>Find string in Online Database</tr>\n");
7584 r->rsprintf("<tr><td>Enter substring (case insensitive)\n");
7585
7586 r->rsprintf("<td><input type=\"text\" size=\"20\" maxlength=\"80\" name=\"value\">\n");
7587 r->rsprintf("</tr>");
7588
7589 r->rsprintf("<tr><td align=center colspan=2>");
7590 r->rsprintf("<input type=submit name=cmd value=Find>");
7591 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7592 r->rsprintf("</tr>");
7593 r->rsprintf("</table>");
7594
7595 r->rsprintf("<input type=hidden name=cmd value=Find>");
7596
7597 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7598 r->rsprintf("</form>\n");
7599 r->rsprintf("</body></html>\r\n");
7600 } else {
7601 show_header(r, "Search results", "GET", "", 0);
7602
7603 r->rsprintf("<table class=\"mtable\">\n");
7604 r->rsprintf("<tr><th colspan=2 class=\"mtableheader\">");
7605 r->rsprintf("Results of search for substring \"%s\"</tr>\n", value);
7606 r->rsprintf("<tr><th class=\"titlerow\">Key<th>Value</tr>\n");
7607
7608 /* start from root */
7609 db_find_key(hDB, 0, "", &hkey);
7610 assert(hkey);
7611
7612 /* scan tree, call "search_callback" for each key */
7614 data.r = r;
7615 data.search_name = value;
7616
7617 db_scan_tree(hDB, hkey, 0, search_callback, (void *)&data);
7618
7619 r->rsprintf("</table>");
7620 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7621 r->rsprintf("</form>\n");
7622 r->rsprintf("</body></html>\r\n");
7623 }
7624}
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
Definition odb.cxx:4767
INT search_callback(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
Definition mhttpd.cxx:1457
Return * r
Definition mhttpd.cxx:1453
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_header()

void show_header ( Return r,
const char title,
const char method,
const char path,
int  refresh 
)

Definition at line 1779 of file mhttpd.cxx.

1780{
1781 HNDLE hDB;
1782 time_t now;
1783 char str[256];
1784
1786
1787 /* header */
1788 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1789 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1790 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1791 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1792 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1793
1794 r->rsprintf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
1795 r->rsprintf("<html><head>\n");
1796
1797 /* style sheet */
1798 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
1799 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1800 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
1801
1802 /* auto refresh */
1803 if (refresh > 0)
1804 r->rsprintf("<meta http-equiv=\"Refresh\" content=\"%02d\">\n", refresh);
1805
1806 r->rsprintf("<title>%s</title></head>\n", title);
1807
1808 mstrlcpy(str, path, sizeof(str));
1809 urlEncode(str, sizeof(str));
1810
1811 if (equal_ustring(method, "POST"))
1812 r->rsprintf
1813 ("<body><form name=\"form1\" method=\"POST\" action=\"%s\" enctype=\"multipart/form-data\">\n\n",
1814 str);
1815 else if (equal_ustring(method, "GET"))
1816 r->rsprintf("<body><form name=\"form1\" method=\"GET\" action=\"%s\">\n\n", str);
1817
1818 /* title row */
1819
1820 std::string exptname;
1821 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
1822 time(&now);
1823}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_help_page()

void show_help_page ( Return r,
const char dec_path 
)

Definition at line 1540 of file mhttpd.cxx.

1541{
1542 const char *s;
1543 char str[256];
1544 int status;
1545
1546 show_header(r, "Help", "", "./", 0);
1547 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
1548 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
1549 show_navigation_bar(r, "Help");
1550
1551 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1552 r->rsprintf(" <tr>\n");
1553 r->rsprintf(" <td class=\"mtableheader\">MIDAS Help Page</td>\n");
1554 r->rsprintf(" </tr>\n");
1555 r->rsprintf(" <tr>\n");
1556 r->rsprintf(" <td>\n");
1557 r->rsprintf(" <table>\n");
1558
1559 r->rsprintf(" <tr>\n");
1560 r->rsprintf(" <td style=\"text-align:right;\">Documentation:</td>\n");
1561 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca\">https://midas.triumf.ca</a></td>\n");
1562 r->rsprintf(" </tr>\n");
1563 r->rsprintf(" <tr>\n");
1564 r->rsprintf(" <td style=\"text-align:right;\">Discussion Forum:</td>\n");
1565 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://midas.triumf.ca/forum/\">https://midas.triumf.ca/forum/</a></td>\n");
1566 r->rsprintf(" </tr>\n");
1567 r->rsprintf(" <tr>\n");
1568 r->rsprintf(" <td style=\"text-align:right;\">Code:</td>\n");
1569 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/\">https://bitbucket.org/tmidas/midas/</a></td>\n");
1570 r->rsprintf(" </tr>\n");
1571 r->rsprintf(" <tr>\n");
1572 r->rsprintf(" <td style=\"text-align:right;\">Report a bug:</td>\n");
1573 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"https://bitbucket.org/tmidas/midas/issues/\">https://bitbucket.org/tmidas/midas/issues/</a></td>\n");
1574 r->rsprintf(" </tr>\n");
1575
1576 r->rsprintf(" <tr>\n");
1577 r->rsprintf(" <td style=\"text-align:right;\">Version:</td>\n");
1578 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_version());
1579 r->rsprintf(" </tr>\n");
1580 r->rsprintf(" <tr>\n");
1581 r->rsprintf(" <td style=\"text-align:right;\">Revision:</td>\n");
1582 std::string rev = cm_get_revision();
1583 std::string url = "https://bitbucket.org/tmidas/midas/commits/";
1584 // rev format looks like this:
1585 // Fri Nov 24 10:15:54 2017 -0800 - midas-2017-07-c-171-gb8928d5c-dirty on branch develop
1586 // -gXXX is the commit hash
1587 // -dirty should be removed from the hash url, if present
1588 // " " before "on branch" should be removed from the hash url
1589 std::string::size_type pos = rev.find("-g");
1590 if (pos != std::string::npos) {
1591 std::string hash = rev.substr(pos+2);
1592 pos = hash.find("-dirty");
1593 if (pos != std::string::npos) {
1594 hash = hash.substr(0, pos);
1595 }
1596 pos = hash.find(" ");
1597 if (pos != std::string::npos) {
1598 hash = hash.substr(0, pos);
1599 }
1600 url += hash;
1601 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"%s\">%s</a></td>\n", url.c_str(), rev.c_str());
1602 } else {
1603 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", rev.c_str());
1604 }
1605 r->rsprintf(" </tr>\n");
1606
1607 r->rsprintf(" <tr>\n");
1608 r->rsprintf(" <td style=\"text-align:right;\">MIDASSYS:</td>\n");
1609 s = getenv("MIDASSYS");
1610 if (!s) s = "(unset)";
1611 mstrlcpy(str, s, sizeof(str));
1612 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", str);
1613 r->rsprintf(" </tr>\n");
1614
1615 r->rsprintf(" <tr>\n");
1616 r->rsprintf(" <td style=\"text-align:right;\">mhttpd current directory:</td>\n");
1617 std::string cwd = ss_getcwd();
1618 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cwd.c_str());
1619 r->rsprintf(" </tr>\n");
1620
1621 r->rsprintf(" <tr>\n");
1622 r->rsprintf(" <td style=\"text-align:right;\">Exptab file:</td>\n");
1623 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_exptab_filename().c_str());
1624 r->rsprintf(" </tr>\n");
1625
1626 r->rsprintf(" <tr>\n");
1627 r->rsprintf(" <td style=\"text-align:right;\">Experiment:</td>\n");
1628 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_experiment_name().c_str());
1629 r->rsprintf(" </tr>\n");
1630
1631 r->rsprintf(" <tr>\n");
1632 r->rsprintf(" <td style=\"text-align:right;\">Experiment directory:</td>\n");
1633 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_path().c_str());
1634 r->rsprintf(" </tr>\n");
1635
1638
1639 if (status == CM_SUCCESS) {
1640 if (list.size() == 1) {
1641 r->rsprintf(" <tr>\n");
1642 r->rsprintf(" <td style=\"text-align:right;\">System logfile:</td>\n");
1643 std::string s;
1644 cm_msg_get_logfile("midas", 0, &s, NULL, NULL);
1645 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", s.c_str());
1646 r->rsprintf(" </tr>\n");
1647 } else {
1648 r->rsprintf(" <tr>\n");
1649 r->rsprintf(" <td style=\"text-align:right;\">Logfiles:</td>\n");
1650 r->rsprintf(" <td style=\"text-align:left;\">\n");
1651 for (unsigned i=0 ; i<list.size() ; i++) {
1652 if (i>0)
1653 r->rsputs("<br />\n");
1654 std::string s;
1655 cm_msg_get_logfile(list[i].c_str(), 0, &s, NULL, NULL);
1656 r->rsputs(s.c_str());
1657 }
1658 r->rsprintf("\n </td>\n");
1659 r->rsprintf(" </tr>\n");
1660 }
1661 }
1662
1663 r->rsprintf(" <tr>\n");
1664 r->rsprintf(" <td style=\"text-align:right;\">Image history:</td>\n");
1665 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", cm_get_history_path("IMAGE").c_str());
1666 r->rsprintf(" </tr>\n");
1667
1668 r->rsprintf(" <tr>\n");
1669 r->rsprintf(" <td style=\"text-align:right;\">Resource paths:</td>\n");
1670 r->rsprintf(" <td style=\"text-align:left;\">");
1671 std::vector<std::string> resource_paths = get_resource_paths();
1672 for (unsigned i=0; i<resource_paths.size(); i++) {
1673 if (i>0)
1674 r->rsputs("<br>");
1676 std::string exp = cm_expand_env(resource_paths[i].c_str());
1677 //printf("%d %d [%s] [%s]\n", resource_paths[i].length(), exp.length(), resource_paths[i].c_str(), exp.c_str());
1678 if (exp != resource_paths[i]) {
1679 r->rsputs(" (");
1680 r->rsputs(exp.c_str());
1681 r->rsputs(")");
1682 }
1683 }
1684 r->rsprintf(" </td>\n");
1685 r->rsprintf(" </tr>\n");
1686
1687 std::string path;
1688
1689 r->rsprintf(" <tr>\n");
1690 r->rsprintf(" <td style=\"text-align:right;\">midas.css:</td>\n");
1691 if (open_resource_file("midas.css", &path, NULL))
1692 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1693 else
1694 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1695 r->rsprintf(" </tr>\n");
1696
1697 r->rsprintf(" <tr>\n");
1698 r->rsprintf(" <td style=\"text-align:right;\">midas.js:</td>\n");
1699 if (open_resource_file("midas.js", &path, NULL))
1700 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1701 else
1702 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1703 r->rsprintf(" </tr>\n");
1704
1705 r->rsprintf(" <tr>\n");
1706 r->rsprintf(" <td style=\"text-align:right;\">controls.js:</td>\n");
1707 if (open_resource_file("controls.js", &path, NULL))
1708 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1709 else
1710 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1711 r->rsprintf(" </tr>\n");
1712
1713 r->rsprintf(" <tr>\n");
1714 r->rsprintf(" <td style=\"text-align:right;\">mhttpd.js:</td>\n");
1715 if (open_resource_file("mhttpd.js", &path, NULL))
1716 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1717 else
1718 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1719 r->rsprintf(" </tr>\n");
1720
1721 r->rsprintf(" <tr>\n");
1722 r->rsprintf(" <td style=\"text-align:right;\">obsolete.js:</td>\n");
1723 if (open_resource_file("obsolete.js", &path, NULL))
1724 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1725 else
1726 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1727 r->rsprintf(" </tr>\n");
1728
1729 r->rsprintf(" <tr>\n");
1730 r->rsprintf(" <td style=\"text-align:right;\">Obsolete mhttpd.css:</td>\n");
1731 if (open_resource_file("mhttpd.css", &path, NULL))
1732 r->rsprintf(" <td style=\"text-align:left;\">%s</td>\n", path.c_str());
1733 else
1734 r->rsprintf(" <td style=\"text-align:left;\">NOT FOUND</td>\n");
1735 r->rsprintf(" </tr>\n");
1736
1737 r->rsprintf(" <tr>\n");
1738 r->rsprintf(" <td style=\"text-align:right;\">JSON-RPC schema:</td>\n");
1739 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?mjsonrpc_schema\">json format</a> or <a href=\"?mjsonrpc_schema_text\">text table format</a></td>\n");
1740 r->rsprintf(" </tr>\n");
1741
1742 r->rsprintf(" <tr>\n");
1743 r->rsprintf(" <td style=\"text-align:right;\">JavaScript examples:</td>\n");
1744 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=example\">example.html</a></td>\n");
1745 r->rsprintf(" </tr>\n");
1746
1747 r->rsprintf(" <tr>\n");
1748 r->rsprintf(" <td style=\"text-align:right;\">Custom page example:</td>\n");
1749 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=custom_example\">custom_example.html</a></td>\n");
1750 r->rsprintf(" </tr>\n");
1751
1752 r->rsprintf(" <tr>\n");
1753 r->rsprintf(" <td style=\"text-align:right;\">MPlot custom plot examples:</td>\n");
1754 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=plot_example\">plot_example.html</a></td>\n");
1755 r->rsprintf(" </tr>\n");
1756
1757 r->rsprintf(" </table>\n");
1758 r->rsprintf(" </td>\n");
1759 r->rsprintf(" </tr>\n");
1760 r->rsprintf("</table>\n");
1761
1762 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1763 r->rsprintf(" <tr>\n");
1764 r->rsprintf(" <td class=\"mtableheader\">Contributions</td>\n");
1765 r->rsprintf(" </tr>\n");
1766 r->rsprintf(" <tr>\n");
1767 r->rsprintf(" <td>\n");
1768 r->rsprintf("Pierre-Andre&nbsp;Amaudruz - Sergio&nbsp;Ballestrero - Suzannah&nbsp;Daviel - Peter&nbsp;Green - Qing&nbsp;Gu - Greg&nbsp;Hackman - Gertjan&nbsp;Hofman - Paul&nbsp;Knowles - Exaos&nbsp;Lee - Thomas&nbsp;Lindner - Shuoyi&nbsp;Ma - Rudi&nbsp;Meier - Bill&nbsp;Mills - Glenn&nbsp;Moloney - Dave&nbsp;Morris - John&nbsp;M&nbsp;O'Donnell - Konstantin&nbsp;Olchanski - Chris&nbsp;Pearson - Renee&nbsp;Poutissou - Stefan&nbsp;Ritt - Zaher&nbsp;Salman - Ryu&nbsp;Sawada - Tamsen&nbsp;Schurman - Ben&nbsp;Smith - Andreas&nbsp;Suter - Jan&nbsp;M.&nbsp;Wouters - Piotr&nbsp;Adam&nbsp;Zolnierczuk\n");
1769 r->rsprintf(" </td>\n");
1770 r->rsprintf(" </tr>\n");
1771 r->rsprintf("</table>\n");
1772
1773 r->rsprintf("</div></form>\n");
1774 r->rsprintf("</body></html>\r\n");
1775}
std::string cm_get_exptab_filename()
Definition midas.cxx:1788
const char * cm_get_version()
Definition midas.cxx:1476
std::string cm_get_experiment_name()
Definition midas.cxx:1580
INT EXPRT cm_msg_facilities(STRING_LIST *list)
Definition midas.cxx:504
void cm_msg_get_logfile(const char *fac, time_t t, std::string *filename, std::string *linkname, std::string *linktarget)
Definition midas.cxx:539
std::vector< std::string > STRING_LIST
Definition midas.h:246
static te_expr * list(state *s)
Definition tinyexpr.c:567
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_hist_config_page()

void show_hist_config_page ( MVOdb odb,
Param p,
Return r,
const char hgroup,
const char hpanel 
)

Definition at line 10519 of file mhttpd.cxx.

10520{
10521 int status;
10522 int max_display_events = 20;
10523 int max_display_tags = 200;
10524 char str[256], hcmd[256];
10525
10526 odb->RI("History/MaxDisplayEvents", &max_display_events, true);
10527 odb->RI("History/MaxDisplayTags", &max_display_tags, true);
10528
10529 mstrlcpy(hcmd, p->getparam("hcmd"), sizeof(hcmd));
10530
10531 if (equal_ustring(hcmd, "Clear history cache")) {
10532 //printf("clear history cache!\n");
10533 strcpy(hcmd, "Refresh");
10535 if (mh)
10536 mh->hs_clear_cache();
10537 }
10538
10539 //printf("cmd [%s]\n", cmd);
10540 //printf("cmdx [%s]\n", p->getparam("cmdx"));
10541
10542 HistPlot hp;
10543
10544 if (equal_ustring(hcmd, "refresh") || equal_ustring(hcmd, "save")) {
10547 } else {
10549 }
10550
10552
10553 if (strlen(p->getparam("seln")) > 0)
10555
10556 //hp->Print();
10557
10558 if (hcmd[0] && equal_ustring(hcmd, "save")) {
10560
10561 if (p->getparam("redir") && *p->getparam("redir"))
10562 redirect(r, p->getparam("redir"));
10563 else {
10564 sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
10565 redirect(r, str);
10566 }
10567 return;
10568 }
10569
10570 show_header(r, "History Config", "GET", "", 0);
10571 r->rsprintf("</table>"); //close header table
10572
10573 r->rsprintf("<table class=\"mtable\">"); //open main table
10574
10575 r->rsprintf("<tr><th colspan=11 class=\"subStatusTitle\">History Panel \"%s\" / \"%s\"</th></tr>\n", hgroup, hpanel);
10576
10577 /* menu buttons */
10578 r->rsprintf("<tr><td colspan=11>\n");
10579
10580 r->rsprintf("<input type=button value=Refresh ");
10581 r->rsprintf("onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">\n");
10582
10583 r->rsprintf("<input type=button value=Save ");
10584 r->rsprintf("onclick=\"document.form1.hcmd.value='Save';document.form1.submit()\">\n");
10585
10586 {
10587 r->rsprintf("<input type=button value=Cancel ");
10588 std::string url = "?cmd=oldhistory&group=";
10589 url += hgroup;
10590 url += "&panel=";
10591 url += hpanel;
10592 url += "&hcmd=Cancel";
10593 if (p->getparam("redir")) {
10594 url += "&redir=";
10595 url += urlEncode(p->getparam("redir"));
10596 }
10597 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10598 }
10599 {
10600 r->rsprintf("<input type=button value=\"Edit in ODB\"");
10601 std::string url = "?cmd=odb&odb_path=";
10602 url += "/History/Display/";
10603 url += urlEncode(hgroup);
10604 url += "/";
10605 url += urlEncode(hpanel);
10606 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10607 }
10608 {
10609 r->rsprintf("<input type=button value=\"Edit in new editor\"");
10610 std::string url = "?cmd=hs_edit";
10611 url += "&group=";
10612 url += urlEncode(hgroup);
10613 url += "&panel=";
10614 url += urlEncode(hpanel);
10615 if (p->getparam("redir")) {
10616 url += "&redir=";
10617 url += urlEncode(p->getparam("redir"));
10618 }
10619 r->rsprintf("onclick=\"window.location.search='%s'\">\n", url.c_str());
10620 }
10621 r->rsprintf("<input type=button value=\"Clear history cache\"");
10622 r->rsprintf("onclick=\"document.form1.hcmd.value='Clear history cache';document.form1.submit()\">\n");
10623 r->rsprintf("<input type=button value=\"Delete panel\"");
10624 r->rsprintf("onclick=\"window.location.search='?cmd=oldhistory&group=%s&panel=%s&hcmd=Delete%%20panel'\">\n", hgroup, hpanel);
10625 r->rsprintf("</td></tr>\n");
10626
10627 r->rsprintf("<tr><td colspan=11>\n");
10628
10629 /* sort_vars */
10630 int sort_vars = *p->getparam("sort_vars");
10631 r->rsprintf("<input type=checkbox %s name=sort_vars value=1 onclick=\"this.form.submit();\">Sort variable names", sort_vars?"checked":"");
10632
10633 /* old_vars */
10634 int old_vars = *p->getparam("old_vars");
10635 r->rsprintf("&nbsp;&nbsp;<input type=checkbox %s name=old_vars value=1 onclick=\"this.form.submit();\">Show deleted and renamed variables", old_vars?"checked":"");
10636
10637 if (hp.show_factor)
10638 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_factor value=1 onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">");
10639 else
10640 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_factor value=1 onclick=\"document.form1.hcmd.value='Refresh';document.form1.submit()\">");
10641 r->rsprintf("Show&nbsp;factor&nbsp;and&nbsp;offset\n");
10642
10643 /* hidden command for refresh */
10644 r->rsprintf("<input type=hidden name=cmd value=Oldhistory>\n");
10645 r->rsprintf("<input type=hidden name=hcmd value=Refresh>\n");
10646 r->rsprintf("<input type=hidden name=panel value=\"%s\">\n", hpanel);
10647 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", hgroup);
10648
10649 if (p->getparam("redir") && *p->getparam("redir"))
10650 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", p->getparam("redir"));
10651
10652 r->rsprintf("</td></tr>\n");
10653
10654 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Time scale (in units 'm', 'h', 'd'):</td>\n");
10655 r->rsprintf("<td colspan=3><input type=text size=12 name=timescale value=%s></td><td colspan=4></td></tr>\n", hp.timescale.c_str());
10656
10657 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Minimum (set to '-inf' for autoscale):</td>\n");
10658 r->rsprintf("<td colspan=3><input type=text size=12 name=minimum value=%f></td><td colspan=4></td></tr>\n", hp.minimum);
10659
10660 r->rsprintf("<tr><td colspan=4 style='text-align:right'>Maximum (set to 'inf' for autoscale):</td>\n");
10661 r->rsprintf("<td colspan=3><input type=text size=12 name=maximum value=%f></td><td colspan=4></td></tr>\n", hp.maximum);
10662
10663 r->rsprintf("<tr><td colspan=11>");
10664
10665 if (hp.zero_ylow)
10666 r->rsprintf("<input type=checkbox checked name=zero_ylow value=1>");
10667 else
10668 r->rsprintf("<input type=checkbox name=zero_ylow value=1>");
10669 r->rsprintf("Zero&nbsp;Y;&nbsp;axis\n");
10670
10671 if (hp.log_axis)
10672 r->rsprintf("<input type=checkbox checked name=log_axis value=1>");
10673 else
10674 r->rsprintf("<input type=checkbox name=log_axis value=1>");
10675 r->rsprintf("Logarithmic&nbsp;Y&nbsp;axis\n");
10676
10677 if (hp.show_run_markers)
10678 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=run_markers value=1>");
10679 else
10680 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=run_markers value=1>");
10681 r->rsprintf("Show&nbsp;run&nbsp;markers\n");
10682
10683 if (hp.show_values)
10684 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_values value=1>");
10685 else
10686 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_values value=1>");
10687 r->rsprintf("Show&nbsp;values&nbsp;of&nbsp;variables\n");
10688
10689 if (hp.show_fill)
10690 r->rsprintf("&nbsp;&nbsp;<input type=checkbox checked name=show_fill value=1>");
10691 else
10692 r->rsprintf("&nbsp;&nbsp;<input type=checkbox name=show_fill value=1>");
10693 r->rsprintf("Show&nbsp;graph&nbsp;fill\n");
10694
10695 r->rsprintf("</td></tr>\n");
10696
10697 /*---- events and variables ----*/
10698
10699 /* get display event name */
10700
10702 if (mh == NULL) {
10703 r->rsprintf(str, "History is not configured\n");
10704 return;
10705 }
10706
10707 time_t t = time(NULL);
10708
10709 if (old_vars)
10710 t = 0;
10711
10712 std::vector<std::string> events;
10713
10714 if (!old_vars)
10716
10717 if (events.size() == 0)
10718 mh->hs_get_events(t, &events);
10719
10720#if 0
10721 for (unsigned i=0; i<events.size(); i++)
10722 printf("event %d: \"%s\"\n", i, events[i].c_str());
10723#endif
10724
10725 // has to be sorted or equipment name code below would not work
10726 //std::sort(events.begin(), events.end(), cmp_events);
10727 std::sort(events.begin(), events.end(), cmp_events1);
10728
10729 if (strlen(p->getparam("cmdx")) > 0) {
10730 r->rsprintf("<tr><th colspan=8 class=\"subStatusTitle\">List of available history variables</th></tr>\n");
10731 r->rsprintf("<tr><th colspan=1>Sel<th colspan=1>Equipment<th colspan=1>Event<th colspan=1>Variable</tr>\n");
10732
10733 std::string cmdx = p->xgetparam("cmdx");
10734 std::string xeqname;
10735
10736 int i=0;
10737 for (unsigned e=0; e<events.size(); e++) {
10738 std::string eqname;
10739 eqname = events[e].substr(0, events[e].find("/"));
10740
10741 if (eqname.length() < 1)
10742 eqname = events[e];
10743
10744 bool once = false;
10745 if (eqname != xeqname)
10746 once = true;
10747
10748 std::string qcmd = "Expand " + eqname;
10749
10750 //printf("param [%s] is [%s]\n", qcmd.c_str(), p->getparam(qcmd.c_str()));
10751
10752 bool collapsed = true;
10753
10754 if (cmdx == qcmd)
10755 collapsed = false;
10756
10757 if (strlen(p->getparam(qcmd.c_str())) > 0)
10758 collapsed = false;
10759
10760 if (collapsed) {
10761 if (eqname == xeqname)
10762 continue;
10763
10764 r->rsprintf("<tr align=left>\n");
10765 r->rsprintf("<td></td>\n");
10766 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10767 r->rsprintf("<td><input type=submit name=cmdx value=\"%s\"></td>\n", qcmd.c_str());
10768 r->rsprintf("<td>%s</td>\n", "");
10769 r->rsprintf("</tr>\n");
10770 xeqname = eqname;
10771 continue;
10772 }
10773
10774 if (once)
10775 r->rsprintf("<tr><input type=hidden name=\"%s\" value=%d></tr>\n", qcmd.c_str(), 1);
10776
10777 std::string rcmd = "Expand " + events[e];
10778
10779 //printf("param [%s] is [%s]\n", rcmd.c_str(), p->getparam(rcmd.c_str()));
10780
10781 collapsed = true;
10782
10783 if (cmdx == rcmd)
10784 collapsed = false;
10785
10786 if (strlen(p->getparam(rcmd.c_str())) > 0)
10787 collapsed = false;
10788
10789 if (collapsed) {
10790 r->rsprintf("<tr align=left>\n");
10791 r->rsprintf("<td></td>\n");
10792 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10793 r->rsprintf("<td>%s</td>\n", events[e].c_str());
10794 r->rsprintf("<td><input type=submit name=cmdx value=\"%s\"></td>\n", rcmd.c_str());
10795 r->rsprintf("</tr>\n");
10796 continue;
10797 }
10798
10799 r->rsprintf("<tr><input type=hidden name=\"%s\" value=%d></tr>\n", rcmd.c_str(), 1);
10800
10801 xeqname = eqname;
10802
10803 std::vector<TAG> tags;
10804
10805 status = mh->hs_get_tags(events[e].c_str(), t, &tags);
10806
10807 if (status == HS_SUCCESS && tags.size() > 0) {
10808
10809 if (sort_vars)
10810 std::sort(tags.begin(), tags.end(), cmp_tags);
10811
10812 for (unsigned v=0; v<tags.size(); v++) {
10813
10814 for (unsigned j=0; j<tags[v].n_data; j++) {
10815 char tagname[256];
10816
10817 if (tags[v].n_data == 1)
10818 sprintf(tagname, "%s", tags[v].name);
10819 else
10820 sprintf(tagname, "%s[%d]", tags[v].name, j);
10821
10822 bool checked = false;
10823#if 0
10824 for (int index=0; index<MAX_VARS; index++) {
10825 if (equal_ustring(vars[index].event_name, events[e].c_str()) && equal_ustring(vars[index].var_name, tagname)) {
10826 checked = true;
10827 break;
10828 }
10829 }
10830#endif
10831
10832 r->rsprintf("<tr align=left>\n");
10833 r->rsprintf("<td><input type=checkbox %s name=\"sel%d\" value=\"%s:%s\"></td>\n", checked?"checked":"", i++, events[e].c_str(), tagname);
10834 r->rsprintf("<td>%s</td>\n", eqname.c_str());
10835 r->rsprintf("<td>%s</td>\n", events[e].c_str());
10836 r->rsprintf("<td>%s</td>\n", tagname);
10837 r->rsprintf("</tr>\n");
10838 }
10839 }
10840 }
10841 }
10842
10843 r->rsprintf("<tr>\n");
10844 r->rsprintf("<td></td>\n");
10845 r->rsprintf("<td>\n");
10846 r->rsprintf("<input type=hidden name=seln value=%d>\n", i);
10847 r->rsprintf("<input type=submit value=\"Add Selected\">\n");
10848 r->rsprintf("</td>\n");
10849 r->rsprintf("</tr>\n");
10850 }
10851
10852 r->rsprintf("<tr><td colspan=11 style='text-align:left'>New history: displayed_value = formula(history_value)</td></tr>\n");
10853 r->rsprintf("<tr><td colspan=11 style='text-align:left'>Old history: displayed_value = offset + factor*(history_value - voffset)</td></tr>\n");
10854 r->rsprintf("<tr><td colspan=11 style='text-align:left'>Formula format: \"3*x+4\", \"10*Math.sin(x)\", etc. all javascript math functions can be used</td></tr>\n");
10855 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To display the raw history value instead of computed formula or offset value, check the \"raw\" checkbox</td></tr>\n");
10856 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To reorder entries: enter new ordering in the \"order\" column and press \"refresh\"</td></tr>\n");
10857 r->rsprintf("<tr><td colspan=11 style='text-align:left'>To delete entries: enter \"-1\" or leave blank the \"order\" column and press \"refresh\"</td></tr>\n");
10858
10859 r->rsprintf("<tr>\n");
10860 r->rsprintf("<th>Col<th>Event<th>Variable<th>Formula<th>Colour<th>Label<th>Raw<th>Order");
10861 if (hp.show_factor) {
10862 r->rsprintf("<th>Factor<th>Offset<th>VOffset");
10863 }
10864 r->rsprintf("</tr>\n");
10865
10866 //print_vars(vars);
10867
10868 size_t nvars = hp.vars.size();
10869 for (size_t index = 0; index <= nvars; index++) {
10870
10871 r->rsprintf("<tr>");
10872
10873 if (index < nvars) {
10874 if (hp.vars[index].colour.empty())
10875 hp.vars[index].colour = NextHistPlotColour(hp);
10876 r->rsprintf("<td style=\"background-color:%s\">&nbsp;<td>\n", hp.vars[index].colour.c_str());
10877 } else {
10878 r->rsprintf("<td>&nbsp;<td>\n");
10879 }
10880
10881 /* event and variable selection */
10882
10883 r->rsprintf("<select name=\"event%d\" size=1 onChange=\"document.form1.submit()\">\n", (int)index);
10884
10885 /* enumerate events */
10886
10887 /* empty option */
10888 r->rsprintf("<option value=\"/empty\">&lt;empty&gt;\n");
10889
10890 if (index==nvars) { // last "empty" entry
10891 for (unsigned e=0; e<events.size(); e++) {
10892 const char *p = events[e].c_str();
10893 r->rsprintf("<option value=\"%s\">%s\n", p, p);
10894 }
10895 } else if ((int)events.size() > max_display_events) { // too many events
10896 r->rsprintf("<option selected value=\"%s\">%s\n", hp.vars[index].event_name.c_str(), hp.vars[index].event_name.c_str());
10897 r->rsprintf("<option>(%d events omitted)\n", (int)events.size());
10898 } else { // show all events
10899 bool found = false;
10900 for (unsigned e=0; e<events.size(); e++) {
10901 const char *s = "";
10902 const char *p = events[e].c_str();
10903 if (equal_ustring(hp.vars[index].event_name.c_str(), p)) {
10904 s = "selected";
10905 found = true;
10906 }
10907 r->rsprintf("<option %s value=\"%s\">%s\n", s, p, p);
10908 }
10909 if (!found) {
10910 const char *p = hp.vars[index].event_name.c_str();
10911 r->rsprintf("<option selected value=\"%s\">%s\n", p, p);
10912 }
10913 }
10914
10915 r->rsprintf("</select></td>\n");
10916
10917 //if (hp.vars[index].order <= 0)
10918 // hp.vars[index].order = (index+1)*10;
10919
10920 if (index < nvars) {
10921 bool found_tag = false;
10922 std::string selected_tag = hp.vars[index].tag_name;
10923
10924 r->rsprintf("<td><select name=\"var%d\">\n", (int)index);
10925
10926 std::vector<TAG> tags;
10927
10928 status = mh->hs_get_tags(hp.vars[index].event_name.c_str(), t, &tags);
10929
10930 if (status == HS_SUCCESS && tags.size() > 0) {
10931
10932 if (/* DISABLES CODE */ (0)) {
10933 printf("Compare %d\n", cmp_names("AAA", "BBB"));
10934 printf("Compare %d\n", cmp_names("BBB", "AAA"));
10935 printf("Compare %d\n", cmp_names("AAA", "AAA"));
10936 printf("Compare %d\n", cmp_names("A", "AAA"));
10937 printf("Compare %d\n", cmp_names("A111", "A1"));
10938 printf("Compare %d\n", cmp_names("A111", "A2"));
10939 printf("Compare %d\n", cmp_names("A111", "A222"));
10940 printf("Compare %d\n", cmp_names("A111a", "A111b"));
10941 }
10942
10943 if (sort_vars)
10944 std::sort(tags.begin(), tags.end(), cmp_tags);
10945
10946 if (/* DISABLES CODE */ (0)) {
10947 printf("Event [%s] %d tags\n", hp.vars[index].event_name.c_str(), (int)tags.size());
10948
10949 for (unsigned v=0; v<tags.size(); v++) {
10950 printf("tag[%d] [%s]\n", v, tags[v].name);
10951 }
10952 }
10953
10954 unsigned count_tags = 0;
10955 for (unsigned v=0; v<tags.size(); v++)
10956 count_tags += tags[v].n_data;
10957
10958 //printf("output %d option tags\n", count_tags);
10959
10960 if ((int)count_tags < max_display_tags) {
10961 for (unsigned v=0; v<tags.size(); v++) {
10962
10963 for (unsigned j=0; j<tags[v].n_data; j++) {
10964 std::string tagname;
10965
10966 if (tags[v].n_data == 1)
10967 tagname = tags[v].name;
10968 else {
10969 char buf[256];
10970 sprintf(buf, "[%d]", j);
10971 tagname = std::string(tags[v].name) + buf;
10972 }
10973
10974 if (equal_ustring(selected_tag.c_str(), tagname.c_str())) {
10975 r->rsprintf("<option selected value=\"%s\">%s\n", tagname.c_str(), tagname.c_str());
10976 found_tag = true;
10977 }
10978 else
10979 r->rsprintf("<option value=\"%s\">%s\n", tagname.c_str(), tagname.c_str());
10980
10981 //printf("%d [%s] [%s] [%s][%s] %d\n", (int)index, vars[index].event_name, tagname, vars[index].var_name, selected_var, found_var);
10982 }
10983 }
10984 }
10985 }
10986
10987 if (!found_tag)
10988 if (hp.vars[index].tag_name.length() > 0)
10989 r->rsprintf("<option selected value=\"%s\">%s\n", hp.vars[index].tag_name.c_str(), hp.vars[index].tag_name.c_str());
10990
10991 r->rsprintf("</select></td>\n");
10992 r->rsprintf("<td><input type=text size=15 maxlength=256 name=\"form%d\" value=%s></td>\n", (int)index, hp.vars[index].formula.c_str());
10993 r->rsprintf("<td><input type=text size=8 maxlength=10 name=\"col%d\" value=%s></td>\n", (int)index, hp.vars[index].colour.c_str());
10994 r->rsprintf("<td><input type=text size=8 maxlength=%d name=\"lab%d\" value=\"%s\"></td>\n", NAME_LENGTH, (int)index, hp.vars[index].label.c_str());
10995 if (hp.vars[index].show_raw_value)
10996 r->rsprintf("<td><input type=checkbox checked name=\"raw%d\" value=1></td>", (int)index);
10997 else
10998 r->rsprintf("<td><input type=checkbox name=\"raw%d\" value=1></td>", (int)index);
10999 r->rsprintf("<td><input type=text size=3 maxlength=32 name=\"ord%d\" value=\"%d\"></td>\n", (int)index, hp.vars[index].order);
11000 if (hp.show_factor) {
11001 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"factor%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].factor);
11002 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"offset%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].offset);
11003 r->rsprintf("<td><input type=text size=6 maxlength=32 name=\"voffset%d\" value=\"%g\"></td>\n", (int)index, hp.vars[index].voffset);
11004 } else {
11005 r->rsprintf("<input type=hidden name=\"factor%d\" value=\"%f\">\n", (int)index, hp.vars[index].factor);
11006 r->rsprintf("<input type=hidden name=\"offset%d\" value=\"%f\">\n", (int)index, hp.vars[index].offset);
11007 r->rsprintf("<input type=hidden name=\"voffset%d\" value=\"%f\">\n", (int)index, hp.vars[index].voffset);
11008 }
11009 } else {
11010 r->rsprintf("<td colspan=2><input type=submit name=cmdx value=\"List all variables\"></td>\n");
11011 }
11012
11013 r->rsprintf("</tr>\n");
11014 }
11015
11016 r->rsprintf("</table>\n");
11017 //r->rsprintf("</form>\n");
11018 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11019 r->rsprintf("</form>\n");
11020 r->rsprintf("</body></html>\r\n");
11021}
virtual int hs_get_events(time_t time_from, std::vector< std::string > *pevents)=0
get list of events that exist(ed) at given time and later (value 0 means "return all events from begi...
virtual int hs_get_tags(const char *event_name, time_t time_from, std::vector< TAG > *ptags)=0
get list of history variables for given event (use event names returned by hs_get_events()) that exis...
virtual int hs_clear_cache()=0
clear internal cache, returns HS_SUCCESS
int hs_read_event_list(std::vector< std::string > *pevents)
static void SaveHistPlotToOdb(MVOdb *odb, const HistPlot &hp, const char *group, const char *panel)
Definition mhttpd.cxx:10405
static void DeleteHistPlotDeleted(HistPlot &hp)
Definition mhttpd.cxx:10481
static void LoadHistPlotFromParam(HistPlot *hp, Param *p)
Definition mhttpd.cxx:10300
const bool cmp_tags(const TAG &a, const TAG &b)
Definition mhttpd.cxx:10043
const bool cmp_events1(const std::string &a, const std::string &b)
Definition mhttpd.cxx:10038
static void SortHistPlotVars(HistPlot &hp)
Definition mhttpd.cxx:10498
static void AddHistPlotSelectedParam(HistPlot &hp, Param *p)
Definition mhttpd.cxx:10377
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_hist_page()

void show_hist_page ( MVOdb odb,
Param p,
Return r,
const char dec_path,
char buffer,
int buffer_size,
int  refresh 
)

Definition at line 11262 of file mhttpd.cxx.

11263{
11265 KEY key, ikey;
11266 int i, j, k, scale, index, width, size, status, labels;
11267 char hgroup[256], hpanel[256], hcmd[256];
11268 const char def_button[][NAME_LENGTH] = { "10m", "1h", "3h", "12h", "24h", "3d", "7d" };
11269
11271
11272 hcmd[0] = hgroup[0] = hpanel[0] = 0;
11273
11274 if (p->getparam("group") && *p->getparam("group"))
11275 mstrlcpy(hgroup, p->getparam("group"), sizeof(hgroup));
11276 if (p->getparam("panel") && *p->getparam("panel"))
11277 mstrlcpy(hpanel, p->getparam("panel"), sizeof(hpanel));
11278 if (p->getparam("hcmd") && *p->getparam("hcmd"))
11279 mstrlcpy(hcmd, p->getparam("hcmd"), sizeof(hcmd));
11280
11281 if (equal_ustring(hcmd, "Reset")) {
11282 std::string redir;
11283 //sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
11284 redir += "?cmd=oldhistory&group=";
11285 redir += hgroup;
11286 redir += "&panel=";
11287 redir += hpanel;
11288 redirect(r, redir.c_str());
11289 return;
11290 }
11291
11292 if (equal_ustring(hcmd, "Query")) {
11293 show_query_page(p, r);
11294 return;
11295 }
11296
11297 if (equal_ustring(hcmd, "Cancel")) {
11298 //sprintf(str, "?cmd=oldhistory&group=%s&panel=%s", hgroup, hpanel);
11299 if (p->getparam("redir") && *p->getparam("redir"))
11300 redirect(r, p->getparam("redir"));
11301 else {
11302 std::string redir;
11303 redir += "?cmd=oldhistory&group=";
11304 redir += hgroup;
11305 redir += "&panel=";
11306 redir += hpanel;
11307 redirect(r, redir.c_str());
11308 }
11309 return;
11310 }
11311
11312 if (equal_ustring(hcmd, "Config") ||
11313 equal_ustring(hcmd, "Save")
11314 || equal_ustring(hcmd, "Clear history cache")
11315 || equal_ustring(hcmd, "Refresh")) {
11316
11317 show_hist_config_page(odb, p, r, hgroup, hpanel);
11318 return;
11319 }
11320
11321 if (equal_ustring(hcmd, "New")) {
11322 show_header(r, "History", "GET", "", 0);
11323
11324 r->rsprintf("<table class=\"dialogTable\">");
11325 r->rsprintf("<tr><th class=\"subStatusTitle\" colspan=2>New History Item</th><tr>");
11326 r->rsprintf("<tr><td align=center colspan=2>\n");
11327 r->rsprintf("Select group: &nbsp;&nbsp;");
11328 r->rsprintf("<select id=\"group\" name=\"group\">\n");
11329
11330 /* list existing groups */
11331 db_find_key(hDB, 0, "/History/Display", &hkey);
11332 if (hkey) {
11333 for (i = 0;; i++) {
11335
11336 if (!hkeyp)
11337 break;
11338
11339 db_get_key(hDB, hkeyp, &key);
11341 r->rsprintf("<option selected>%s</option>\n", key.name);
11342 else
11343 r->rsprintf("<option>%s</option>\n", key.name);
11344 }
11345 }
11346 if (!hkey || i == 0)
11347 r->rsprintf("<option>Default</option>\n");
11348 r->rsprintf("</select><p>\n");
11349
11350 r->rsprintf("Or enter new group name: &nbsp;&nbsp;");
11351 r->rsprintf("<input type=text size=15 maxlength=31 id=new_group name=new_group>\n");
11352
11353 r->rsprintf("<tr><td align=center colspan=2>\n");
11354 r->rsprintf("<br>Panel name: &nbsp;&nbsp;");
11355 r->rsprintf("<input type=text size=15 maxlength=31 id=panel name=panel><br><br>\n");
11356 r->rsprintf("</td></tr>\n");
11357
11358 r->rsprintf("<tr><td align=center colspan=2>");
11359 std::string str = "?cmd=oldhistory&hcmd=createnew";
11360 str += "&new_group='+document.getElementById('new_group').value+'";
11361 str += "&group='+document.getElementById('group').value+'";
11362 str += "&panel='+document.getElementById('panel').value+'";
11363 r->rsprintf("<input type=button value=Submit onclick=\"window.location.search='%s'\">\n", str.c_str());
11364 r->rsprintf("</td></tr>\n");
11365
11366 r->rsprintf("</table>\r\n");
11367 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11368 r->rsprintf("</form>\n");
11369 r->rsprintf("</body></html>\r\n");
11370 return;
11371 }
11372
11373 if (equal_ustring(hcmd, "Delete Panel")) {
11374 std::string path;
11375 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
11376 path += "/History/Display/";
11377 path += hgroup;
11378 path += "/";
11379 path += hpanel;
11380 if (db_find_key(hDB, 0, path.c_str(), &hkey)==DB_SUCCESS)
11382
11383 redirect(r, "?cmd=oldhistory");
11384 return;
11385 }
11386
11387 if (equal_ustring(hcmd, "createnew")) {
11388
11389 /* strip leading/trailing spaces */
11390 while (hpanel[0] == ' ') {
11391 char str[256];
11392 mstrlcpy(str, hpanel+1, sizeof(str));
11393 mstrlcpy(hpanel, str, sizeof(hpanel));
11394 }
11395 while (strlen(hpanel)> 1 && hpanel[strlen(hpanel)-1] == ' ')
11396 hpanel[strlen(hpanel)-1] = 0;
11397
11398 /* use new group if present */
11399 if (p->isparam("new_group") && *p->getparam("new_group"))
11400 mstrlcpy(hgroup, p->getparam("new_group"), sizeof(hgroup));
11401
11402 /* configure that panel */
11403 show_hist_config_page(odb, p, r, hgroup, hpanel);
11404 return;
11405 }
11406
11407 const char* pscale = p->getparam("scale");
11408 if (pscale == NULL || *pscale == 0)
11409 pscale = p->getparam("hscale");
11410 const char* pwidth = p->getparam("width");
11411 if (pwidth == NULL || *pwidth == 0)
11412 pwidth = p->getparam("hwidth");
11413 const char* pheight = p->getparam("height");
11414 if (pheight == NULL || *pheight == 0)
11415 pheight = p->getparam("hheight");
11416 const char* pindex = p->getparam("index");
11417 if (pindex == NULL || *pindex == 0)
11418 pindex = p->getparam("hindex");
11419
11420 labels = 1;
11421 if (*p->getparam("labels") && atoi(p->getparam("labels")) == 0)
11422 labels = 0;
11423
11424 std::string bgcolor = "FFFFFF";
11425 if (*p->getparam("bgcolor"))
11426 bgcolor = p->xgetparam("bgcolor");
11427
11428 std::string fgcolor = "000000";
11429 if (*p->getparam("fgcolor"))
11430 fgcolor = p->xgetparam("fgcolor");
11431
11432 std::string gridcolor = "A0A0A0";
11433 if (*p->getparam("gcolor"))
11434 gridcolor = p->xgetparam("gcolor");
11435
11436 /* evaluate scale and offset */
11437
11438 time_t endtime = 0;
11439 if (p->isparam("time"))
11440 endtime = string_to_time(p->getparam("time"));
11441 else if (p->isparam("htime"))
11442 endtime = string_to_time(p->getparam("htime"));
11443
11444 if (pscale && *pscale)
11445 scale = time_to_sec(pscale);
11446 else
11447 scale = 0;
11448
11449 index = -1;
11450 if (pindex && *pindex)
11451 index = atoi(pindex);
11452
11453#ifdef BROKEN
11454 if (equal_ustring(hcmd, "Create ELog")) {
11455 std::string xurl;
11456 status = db_get_value_string(hDB, 0, "/Elog/URL", 0, &xurl, FALSE);
11457 if (status == DB_SUCCESS) {
11458 char url[256];
11459 get_elog_url(url, sizeof(url));
11460
11461 /*---- use external ELOG ----*/
11462 fsize = 100000;
11463 char* fbuffer = (char*)M_MALLOC(fsize);
11464 assert(fbuffer != NULL);
11465
11466 int width = 640;
11467 int height = 400;
11468
11469 if (equal_ustring(pmag, "Large")) {
11470 width = 1024;
11471 height = 768;
11472 } else if (equal_ustring(pmag, "Small")) {
11473 width = 320;
11474 height = 200;
11475 } else if (atoi(pmag) > 0) {
11476 width = atoi(pmag);
11477 height = 200;
11478 }
11479
11480 printf("hereA\n");
11481 generate_hist_graph(odb, r, hgroup, hpanel, fbuffer, &fsize, width, height, endtime, scale, index, labels, bgcolor.c_str(), fgcolor.c_str(), gridcolor.c_str());
11482
11483 /* save temporary file */
11484 std::string dir;
11485 db_get_value_string(hDB, 0, "/Elog/Logbook Dir", 0, &dir, TRUE);
11486 if (dir.length() > 0 && dir[dir.length()-1] != DIR_SEPARATOR)
11487 dir += DIR_SEPARATOR_STR;
11488
11489 time_t now = time(NULL);
11490 localtime_r(&now, &tms);
11491
11492 std::string file_name = msprintf("%02d%02d%02d_%02d%02d%02d_%s.gif",
11493 tms.tm_year % 100, tms.tm_mon + 1, tms.tm_mday,
11494 tms.tm_hour, tms.tm_min, tms.tm_sec, hpanel);
11495 std::string fname = dir + file_name;
11496
11497 /* save attachment */
11498 fh = open(fname.c_str(), O_CREAT | O_RDWR | O_BINARY, 0644);
11499 if (fh < 0) {
11500 cm_msg(MERROR, "show_hist_page", "Cannot write attachment file \"%s\", open() errno %d (%s)", fname.c_str(), errno, strerror(errno));
11501 } else {
11502 int wr = write(fh, fbuffer, fsize);
11503 if (wr != fsize) {
11504 cm_msg(MERROR, "show_hist_page", "Cannot write attachment file \"%s\", write(%d) returned %d, errno %d (%s)", fname.c_str(), fsize, wr, errno, strerror(errno));
11505 }
11506 close(fh);
11507 }
11508
11509 /* redirect to ELOG */
11510 if (strlen(url) > 1 && url[strlen(url)-1] != '/')
11511 mstrlcat(url, "/", sizeof(url));
11512 mstrlcat(url, "?cmd=New&fa=", sizeof(url));
11513 mstrlcat(url, file_name, sizeof(url));
11514 redirect(r, url);
11515
11516 M_FREE(fbuffer);
11517 return;
11518
11519 } else {
11520 /*---- use internal ELOG ----*/
11521 std::string str = msprintf("\\HS\\%s.gif", hpanel);
11522 if (p->getparam("hscale") && *p->getparam("hscale"))
11523 str += msprintf("?scale=%s", p->getparam("hscale"));
11524 if (p->getparam("htime") && *p->getparam("htime")) {
11525 if (strchr(str.c_str(), '?'))
11526 str += "&";
11527 else
11528 str += "?";
11529 str += msprintf("time=%s", p->getparam("htime"));
11530 }
11531 //if (p->getparam("hoffset") && *p->getparam("hoffset")) {
11532 // if (strchr(str, '?'))
11533 // mstrlcat(str, "&", sizeof(str));
11534 // else
11535 // mstrlcat(str, "?", sizeof(str));
11536 // sprintf(str + strlen(str), "offset=%s", p->getparam("hoffset"));
11537 //}
11538 if (p->getparam("hwidth") && *p->getparam("hwidth")) {
11539 if (strchr(str.c_str(), '?'))
11540 str += "&";
11541 else
11542 str += "?";
11543 str += msprintf("width=%s", p->getparam("hwidth"));
11544 }
11545 if (p->getparam("hindex") && *p->getparam("hindex")) {
11546 if (strchr(str.c_str(), '?'))
11547 str += "&";
11548 else
11549 str += "?";
11550 str += msprintf("index=%s", p->getparam("hindex"));
11551 }
11552
11553 show_elog_new(r, hpanel, NULL, FALSE, str.c_str(), "../../EL/");
11554 return;
11555 }
11556 }
11557#endif
11558
11559 if (equal_ustring(hcmd, "Export")) {
11560 export_hist(odb, r, hgroup, hpanel, endtime, scale, index, labels);
11561 return;
11562 }
11563
11564 if (strstr(dec_path, ".gif")) {
11565 int width = 640;
11566 int height = 400;
11567 if (equal_ustring(pwidth, "Large")) {
11568 width = 1024;
11569 height = 768;
11570 } else if (equal_ustring(pwidth, "Small")) {
11571 width = 320;
11572 height = 200;
11573 } else if (atoi(pwidth) > 0) {
11574 width = atoi(pwidth);
11575 if (atoi(pheight) > 0)
11576 height = atoi(pheight);
11577 else
11578 height = (int)(0.625 * width);
11579 }
11580
11581 //printf("dec_path [%s], buf %p, %p, width %d, height %d, endtime %ld, scale %d, index %d, labels %d\n", dec_path, buffer, buffer_size, width, height, endtime, scale, index, labels);
11582
11583 generate_hist_graph(odb, r, hgroup, hpanel, buffer, buffer_size, width, height, endtime, scale, index, labels, bgcolor.c_str(), fgcolor.c_str(), gridcolor.c_str());
11584
11585 return;
11586 }
11587
11588 if (history_mode && index < 0)
11589 return;
11590
11591 time_t now = time(NULL);
11592
11593 /* evaluate offset shift */
11594 if (equal_ustring(p->getparam("shift"), "leftmaxall")) {
11595 if (endtime == 0)
11596 endtime = now;
11597 time_t last_written = 0;
11598 status = get_hist_last_written(odb, hgroup, hpanel, endtime, index, 1, &last_written);
11599 if (status == HS_SUCCESS)
11600 endtime = last_written + scale/2;
11601 }
11602
11603 if (equal_ustring(p->getparam("shift"), "leftmax")) {
11604 if (endtime == 0)
11605 endtime = now;
11606 time_t last_written = 0;
11607 status = get_hist_last_written(odb, hgroup, hpanel, endtime, index, 0, &last_written);
11608 if (status == HS_SUCCESS)
11609 if (last_written != endtime)
11610 endtime = last_written + scale/2;
11611 }
11612
11613 if (equal_ustring(p->getparam("shift"), "left")) {
11614 if (endtime == 0)
11615 endtime = now;
11616 endtime -= scale/2;
11617 //offset -= scale / 2;
11618 }
11619
11620 if (equal_ustring(p->getparam("shift"), "right")) {
11621 if (endtime == 0)
11622 endtime = now;
11623 endtime += scale/2;
11624 if (endtime > now)
11625 endtime = now;
11626 }
11627
11628 if (equal_ustring(p->getparam("shift"), "rightmax")) {
11629 endtime = 0;
11630 }
11631
11632 if (equal_ustring(p->getparam("shift"), "zoomin")) {
11633 if (endtime == 0)
11634 endtime = now;
11635 endtime -= scale / 4;
11636 scale /= 2;
11637 }
11638
11639 if (equal_ustring(p->getparam("shift"), "zoomout")) {
11640 if (endtime == 0)
11641 endtime = now;
11642 endtime += scale / 2;
11643 if (endtime > now)
11644 endtime = now;
11645 scale *= 2;
11646 }
11647
11648 int xrefresh = refresh;
11649 if (endtime != 0)
11650 xrefresh = 0;
11651 show_header(r, hpanel, "GET", "", xrefresh);
11652
11653 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
11654 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
11655 show_navigation_bar(r, "History");
11656
11657 r->rsprintf("<table class=\"mtable\">");
11658 r->rsprintf("<tr><th class=\"mtableheader\" colspan=2>History</th></tr>");
11659
11660 {
11661 /* check if panel exists */
11662 std::string path;
11663 //sprintf(str, "/History/Display/%s/%s", hgroup, hpanel);
11664 path += "/History/Display/";
11665 path += hgroup;
11666 path += "/";
11667 path += hpanel;
11668 status = db_find_key(hDB, 0, path.c_str(), &hkey);
11669 if (status != DB_SUCCESS && !equal_ustring(hpanel, "All") && !equal_ustring(hpanel,"")) {
11670 r->rsprintf("<h1>Error: History panel \"%s\" in group \"%s\" does not exist</h1>\n", hpanel, hgroup);
11671 r->rsprintf("</table>\r\n");
11672 r->rsprintf("</div>\n"); // closing for <div id="mmain">
11673 r->rsprintf("</form>\n");
11674 r->rsprintf("</body></html>\r\n");
11675 return;
11676 }
11677 }
11678
11679 /* define hidden field for parameters */
11680 if (pscale && *pscale)
11681 r->rsprintf("<input type=hidden name=hscale id=hscale value=%d>\n", scale);
11682 else {
11683 /* if no scale and offset given, get it from default */
11684 if (hpanel[0] && !equal_ustring(hpanel, "All") && hgroup[0]) {
11685 std::string path;
11686 path += "/History/Display/";
11687 path += hgroup;
11688 path += "/";
11689 path += hpanel;
11690 path += "/Timescale";
11691
11692 std::string scalestr = "1h";
11693 status = db_get_value_string(hDB, 0, path.c_str(), 0, &scalestr, TRUE);
11694 if (status != DB_SUCCESS) {
11695 /* delete old integer key */
11696 db_find_key(hDB, 0, path.c_str(), &hkey);
11697 if (hkey)
11699
11700 scalestr = "1h";
11701 db_get_value_string(hDB, 0, path.c_str(), 0, &scalestr, TRUE);
11702 }
11703
11704 r->rsprintf("<input type=hidden name=hscale id=hscale value=%s>\n", scalestr.c_str());
11705 scale = time_to_sec(scalestr.c_str());
11706 }
11707 }
11708
11709 if (endtime != 0)
11710 r->rsprintf("<input type=hidden name=htime id=htime value=%s>\n", time_to_string(endtime).c_str());
11711 if (pwidth && *pwidth)
11712 r->rsprintf("<input type=hidden name=hwidth id=hwidth value=%s>\n", pwidth);
11713 if (pheight && *pheight)
11714 r->rsprintf("<input type=hidden name=hheight id=hheight value=%s>\n", pheight);
11715 if (pindex && *pindex)
11716 r->rsprintf("<input type=hidden name=hindex id=hindex value=%s>\n", pindex);
11717
11718 r->rsprintf("</td></tr>\n");
11719
11720 if (hgroup[0] == 0) {
11721 /* "New" button */
11722 r->rsprintf("<tr><td colspan=2><input type=\"button\" name=\"New\" value=\"New\" ");
11723 r->rsprintf("onClick=\"window.location.href='?cmd=oldhistory&hcmd=New'\"></td></tr>\n");
11724
11725 /* links for history panels */
11726 r->rsprintf("<tr><td colspan=2 style=\"text-align:left;\">\n");
11727 if (!hpanel[0])
11728 r->rsprintf("<b>Please select panel:</b><br>\n");
11729
11730 /* table for panel selection */
11731 r->rsprintf("<table class=\"historyTable\">");
11732
11733 /* "All" link */
11734 r->rsprintf("<tr><td colspan=2 class=\"titleCell\">\n");
11735 if (equal_ustring(hgroup, "All"))
11736 r->rsprintf("All &nbsp;&nbsp;");
11737 else
11738 r->rsprintf("<a href=\"?cmd=oldhistory&group=All\">ALL</a>\n");
11739 r->rsprintf("</td></tr>\n");
11740
11741 /* Setup History table links */
11742 db_find_key(hDB, 0, "/History/Display", &hkey);
11743 if (!hkey) {
11744 /* create default panel */
11745 char str[256];
11746 strcpy(str, "System:Trigger per sec.");
11747 strcpy(str + 2 * NAME_LENGTH, "System:Trigger kB per sec.");
11748 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Variables", str, 64, 2, TID_STRING);
11749 strcpy(str, "1h");
11750 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Time Scale", str, NAME_LENGTH, 1, TID_STRING);
11751
11752 strcpy(str, "1h");
11753 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Timescale", str, NAME_LENGTH, 1, TID_STRING);
11754 i = 1;
11755 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Zero ylow", &i, sizeof(BOOL), 1, TID_BOOL);
11756 i = 1;
11757 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Show run markers", &i, sizeof(BOOL), 1, TID_BOOL);
11758
11759 strcpy(str, "");
11760 db_set_value(hDB, 0, "/History/Display/Default/Trigger rate/Formula", str, 64, 1, TID_STRING);
11761 db_set_value_index(hDB, 0, "/History/Display/Default/Trigger rate/Formula", str, 64, 1, TID_STRING, FALSE);
11762 }
11763
11764 db_find_key(hDB, 0, "/History/Display", &hkey);
11765 if (hkey) {
11766 for (i = 0;; i++) {
11768
11769 if (!hkeyp)
11770 break;
11771
11772 // Group key
11773 db_get_key(hDB, hkeyp, &key);
11774
11775 char enc_name[256];
11776 mstrlcpy(enc_name, key.name, sizeof(enc_name));
11777 urlEncode(enc_name, sizeof(enc_name));
11778
11780 r->rsprintf("<tr><td class=\"titleCell\">%s</td>\n<td>", key.name);
11781 else
11782 r->rsprintf("<tr><td class=\"titleCell\"><a href=\"?cmd=oldhistory&group=%s\">%s</a></td>\n<td>", enc_name, key.name);
11783
11784 for (j = 0;; j++) {
11785 // scan items
11787
11788 if (!hikeyp) {
11789 r->rsprintf("</tr>");
11790 break;
11791 }
11792 // Item key
11794
11795 char enc_iname[256];
11796 mstrlcpy(enc_iname, ikey.name, sizeof(enc_iname));
11797 urlEncode(enc_iname, sizeof(enc_iname));
11798
11799 if (equal_ustring(hpanel, ikey.name))
11800 r->rsprintf("<small><b>%s</b></small> &nbsp;", ikey.name);
11801 else
11802 r->rsprintf("<small><a href=\"?cmd=oldhistory&group=%s&panel=%s\">%s</a></small> &nbsp;\n", enc_name, enc_iname, ikey.name);
11803 }
11804 }
11805 }
11806
11807 r->rsprintf("</table></tr>\n");
11808
11809 } else {
11810 int found = 0;
11811
11812 /* show drop-down selectors */
11813 r->rsprintf("<tr><td colspan=2>\n");
11814
11815 r->rsprintf("Group:\n");
11816
11817 r->rsprintf("<select title=\"Select group\" id=\"fgroup\" onChange=\"window.location.search='?cmd=oldhistory&group='+document.getElementById('fgroup').value;\">\n");
11818
11819 db_find_key(hDB, 0, "/History/Display", &hkey);
11820 if (hkey) {
11821 hkeyp = 0;
11822 for (i = 0;; i++) {
11824
11825 if (!hikeyp)
11826 break;
11827
11828 if (i == 0)
11829 hkeyp = hikeyp;
11830
11831 // Group key
11833
11834 if (equal_ustring(key.name, hgroup)) {
11835 r->rsprintf("<option selected value=\"%s\">%s\n", key.name, key.name);
11836 hkeyp = hikeyp;
11837 } else
11838 r->rsprintf("<option value=\"%s\">%s\n", key.name, key.name);
11839 }
11840
11841 if (equal_ustring("ALL", hgroup)) {
11842 r->rsprintf("<option selected value=\"%s\">%s\n", "ALL", "ALL");
11843 } else {
11844 r->rsprintf("<option value=\"%s\">%s\n", "ALL", "ALL");
11845 }
11846
11847 r->rsprintf("</select>\n");
11848 r->rsprintf("&nbsp;&nbsp;Panel:\n");
11849 r->rsprintf("<select title=\"Select panel\" id=\"fpanel\" ");
11850 r->rsprintf("onChange=\"window.location.search='?cmd=oldhistory&group='+document.getElementById('fgroup').value+");
11851 r->rsprintf("'&panel='+document.getElementById('fpanel').value;\">\n");
11852
11853 found = 0;
11854 if (hkeyp) {
11855 for (i = 0;; i++) {
11856 // scan panels
11858
11859 if (!hikeyp)
11860 break;
11861
11862 // Item key
11864
11865 if (equal_ustring(hpanel, key.name)) {
11866 r->rsprintf("<option selected value=\"%s\">%s\n", key.name, key.name);
11867 found = 1;
11868 } else
11869 r->rsprintf("<option value=\"%s\">%s\n", key.name, key.name);
11870 }
11871 }
11872
11873 if (found)
11874 r->rsprintf("<option value=\"\">- all -\n");
11875 else
11876 r->rsprintf("<option selected value=\"\">- all -\n");
11877
11878 r->rsprintf("</select>\n");
11879 }
11880
11881 r->rsprintf("<noscript>\n");
11882 r->rsprintf("<input type=submit value=\"Go\">\n");
11883 r->rsprintf("</noscript>\n");
11884
11885 r->rsprintf("&nbsp;&nbsp;<input type=\"button\" name=\"New\" value=\"New\" ");
11886 r->rsprintf("onClick=\"window.location.href='?cmd=oldhistory&hcmd=New&group=%s'\">\n", hgroup);
11887
11888 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"Reset\" onClick=\"window.location.href='?cmd=oldhistory&hcmd=Reset&group=%s&panel=%s'\">\n", hgroup, hpanel);
11889
11890 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"Query\" onClick=\"window.location.href='?cmd=oldhistory&hcmd=Query&group=%s&panel=%s'\">\n", hgroup, hpanel);
11891
11892 double xendtime = endtime;
11893 if (xendtime == 0)
11894 xendtime = now;
11895 double xstarttime = xendtime - scale;
11896
11897 r->rsprintf("<input type=\"button\" name=\"Cmd\" value=\"New history\" onClick=\"window.location.href='?cmd=history&group=%s&panel=%s&A=%.0f&B=%.0f'\">\n", hgroup, hpanel, xstarttime, xendtime);
11898
11899 r->rsprintf("</td></tr>\n");
11900 }
11901
11902 //printf("hgroup [%s] hpanel [%s]\n", hgroup, hpanel);
11903
11904 /* check if whole group should be displayed */
11905 if (hgroup[0] && !equal_ustring(hgroup, "ALL") && hpanel[0] == 0) {
11906 std::string strwidth = "Small";
11907 db_get_value_string(hDB, 0, "/History/Display Settings/Width Group", 0, &strwidth, TRUE);
11908
11909 std::string path;
11910 path += "/History/Display/";
11911 path += hgroup;
11912 db_find_key(hDB, 0, path.c_str(), &hkey);
11913 if (hkey) {
11914 for (i = 0 ;; i++) { // scan group
11916
11917 if (!hikeyp)
11918 break;
11919
11921
11922 char enc_name[256];
11923 mstrlcpy(enc_name, key.name, sizeof(enc_name));
11924 urlEncode(enc_name, sizeof(enc_name));
11925
11926 std::string ref;
11927 ref += "graph.gif?width=";
11928 ref += strwidth;
11929 ref += "&cmd=oldhistory&group=";
11930 ref += hgroup;
11931 ref += "&panel=";
11932 ref += enc_name;
11933
11934 std::string ref2;
11935 ref2 += "?cmd=oldhistory&group=";
11936 ref2 += hgroup;
11937 ref2 += "&panel=";
11938 ref2 += enc_name;
11939
11940 if (endtime != 0) {
11941 char tmp[256];
11942 sprintf(tmp, "time=%s&scale=%d", time_to_string(endtime).c_str(), scale);
11943 ref += "&";
11944 ref += tmp;
11945 ref2 += "?";
11946 ref2 += tmp;
11947 }
11948
11949 if (i % 2 == 0)
11950 r->rsprintf("<tr><td><a href=\"%s\"><img src=\"%s\"></a>\n", ref2.c_str(), ref.c_str());
11951 else
11952 r->rsprintf("<td><a href=\"%s\"><img src=\"%s\"></a></tr>\n", ref2.c_str(), ref.c_str());
11953 }
11954
11955 } else {
11956 r->rsprintf("Group \"%s\" not found", hgroup);
11957 }
11958 }
11959
11960 /* image panel */
11961 else if (hpanel[0] && !equal_ustring(hpanel, "All")) {
11962 /* navigation links */
11963 r->rsprintf("<tr><td>\n");
11964
11965 std::string path;
11966 path += "/History/Display/";
11967 path += hgroup;
11968 path += "/";
11969 path += hpanel;
11970 path += "/Buttons";
11971 db_find_key(hDB, 0, path.c_str(), &hkeybutton);
11972 if (hkeybutton == 0) {
11973 /* create default buttons */
11974 db_create_key(hDB, 0, path.c_str(), TID_STRING);
11975 status = db_find_key(hDB, 0, path.c_str(), &hkeybutton);
11976 if (status != DB_SUCCESS || !hkey) {
11977 cm_msg(MERROR, "show_hist_page", "Cannot create history panel with invalid ODB path \"%s\"", path.c_str());
11978 return;
11979 }
11981 }
11982
11983 r->rsprintf("<script>\n");
11984 r->rsprintf("function histDisp(p) {\n");
11985 r->rsprintf(" var params = '?cmd=oldhistory&group=%s&panel=%s';\n", hgroup, hpanel);
11986 r->rsprintf(" params += '&'+p;\n");
11987 r->rsprintf(" if (document.getElementById(\'hscale\') !== null)\n");
11988 r->rsprintf(" params += '&hscale='+document.getElementById(\'hscale\').value;\n");
11989 r->rsprintf(" if (document.getElementById(\'htime\') !== null)\n");
11990 r->rsprintf(" params += '&htime='+document.getElementById(\'htime\').value;\n");
11991 r->rsprintf(" if (document.getElementById(\'hwdith\') !== null)\n");
11992 r->rsprintf(" params += '&hwidth='+document.getElementById(\'hwidth\').value;\n");
11993 r->rsprintf(" if (document.getElementById(\'hindex\') !== null)\n");
11994 r->rsprintf(" params += '&hindex='+document.getElementById(\'hindex\').value;\n");
11995 r->rsprintf(" window.location.search = params;\n");
11996 r->rsprintf("}\n\n");
11997 r->rsprintf("</script>\n");
11998
12000
12001 for (i = 0; i < key.num_values; i++) {
12002 char str[256];
12003 size = sizeof(str);
12005 r->rsprintf("<input type=\"button\" title=\"display last %s\" value=%s onclick=\"histDisp('scale=%s')\">\n", str, str, str);
12006 }
12007
12008 r->rsprintf("<input type=\"button\" value=\"<<<\" title=\"go back in time to last available data for all variables on the plot\" onclick=\"histDisp('shift=leftmaxall')\">");
12009 r->rsprintf("<input type=\"button\" value=\"<<\" title=\"go back in time to last available data\" onclick=\"histDisp('shift=leftmax')\">");
12010 r->rsprintf("<input type=\"button\" value=\"<\" title=\"go back in time\" onclick=\"histDisp('shift=left')\">");
12011
12012 r->rsprintf("<input type=\"button\" value=\" + \" title=\"zoom in\" onclick=\"histDisp('shift=zoomin')\">");
12013 r->rsprintf("<input type=\"button\" value=\" - \" title=\"zoom out\" onclick=\"histDisp('shift=zoomout')\">");
12014
12015 if (endtime != 0) {
12016 r->rsprintf("<input type=\"button\" value=\">\" title=\"go forward in time\" onclick=\"histDisp('shift=right')\">");
12017 r->rsprintf("<input type=\"button\" value=\">>\" title=\"go to currently updated fresh data\" onclick=\"histDisp('shift=rightmax')\">");
12018 }
12019
12020 r->rsprintf("<td>\n");
12021 r->rsprintf("<input type=\"button\" value=\"Large\" title=\"large display\" onclick=\"histDisp('width=Large')\">\n");
12022 r->rsprintf("<input type=\"button\" value=\"Small\" title=\"large display\" onclick=\"histDisp('width=Small')\">\n");
12023 r->rsprintf("<input type=\"button\" value=\"Create Elog\" title=\"large display\" onclick=\"histDisp('hcmd=Create Elog')\">\n");
12024 r->rsprintf("<input type=\"button\" value=\"Config\" title=\"large display\" onclick=\"histDisp('hcmd=Config')\">\n");
12025 r->rsprintf("<input type=\"button\" value=\"Export\" title=\"large display\" onclick=\"histDisp('hcmd=Export')\">\n");
12026 r->rsprintf("</tr>\n");
12027
12028 char paramstr[256];
12029
12030 paramstr[0] = 0;
12031 sprintf(paramstr + strlen(paramstr), "&scale=%d", scale);
12032 if (endtime != 0)
12034 if (pwidth && *pwidth)
12035 sprintf(paramstr + strlen(paramstr), "&width=%s", pwidth);
12036 else {
12037 std::string wi = "640";
12038 db_get_value_string(hDB, 0, "/History/Display Settings/Width Individual", 0, &wi, TRUE);
12039 sprintf(paramstr + strlen(paramstr), "&width=%s", wi.c_str());
12040 }
12041 if (pheight && *pheight)
12042 sprintf(paramstr + strlen(paramstr), "&height=%s", pheight);
12043
12044 /* define image map */
12045 r->rsprintf("<map name=\"%s\">\r\n", hpanel);
12046
12047 if (!(pindex && *pindex)) {
12048 std::string path;
12049 path += "/History/Display/";
12050 path += hgroup;
12051 path += "/";
12052 path += hpanel;
12053 path += "/Variables";
12054 db_find_key(hDB, 0, path.c_str(), &hkey);
12055 if (hkey) {
12056 db_get_key(hDB, hkey, &key);
12057
12058 for (i = 0; i < key.num_values; i++) {
12059 std::string ref;
12060 //if (paramstr[0]) {
12061 // sprintf(ref, "?cmd=oldhistory&group=%s&panel=%s&%s&index=%d", hgroup, hpanel, paramstr, i);
12062 //} else {
12063 // sprintf(ref, "?cmd=oldhistory&group=%s&panel=%s&index=%d", hgroup, hpanel, i);
12064 //}
12065
12066 ref += "?cmd=oldhistory&group=";
12067 ref += hgroup;
12068 ref += "&panel=";
12069 ref += hpanel;
12070 if (paramstr[0]) {
12071 ref += "&";
12072 ref += paramstr;
12073 }
12074 ref += "&index=";
12075 ref += toString(i);
12076
12077 r->rsprintf(" <area shape=rect coords=\"%d,%d,%d,%d\" href=\"%s\">\r\n", 30, 31 + 23 * i, 150, 30 + 23 * i + 17, ref.c_str());
12078 }
12079 }
12080 } else {
12081 std::string ref = "?cmd=oldhistory&group=";
12082 ref += hgroup;
12083 ref += "&panel=";
12084 ref += hpanel;
12085
12086 if (paramstr[0]) {
12087 ref += "&";
12088 ref += paramstr;
12089 }
12090
12091 if (equal_ustring(pwidth, "Large"))
12092 width = 1024;
12093 else if (equal_ustring(pwidth, "Small"))
12094 width = 320;
12095 else if (atoi(pwidth) > 0)
12096 width = atoi(pwidth);
12097 else
12098 width = 640;
12099
12100 r->rsprintf(" <area shape=rect coords=\"%d,%d,%d,%d\" href=\"%s\">\r\n", 0, 0, width, 20, ref.c_str());
12101 }
12102
12103 r->rsprintf("</map>\r\n");
12104
12105 /* Display individual panels */
12106 if (pindex && *pindex)
12107 sprintf(paramstr + strlen(paramstr), "&index=%s", pindex);
12108
12109 std::string ref;
12110 //sprintf(ref, "graph.gif?cmd=oldhistory&group=%s&panel=%s%s", hgroup, hpanel, paramstr);
12111 ref += "graph.gif?cmd=oldhistory&group=";
12112 ref += hgroup;
12113 ref += "&panel=";
12114 ref += hpanel;
12115 ref += paramstr;
12116
12117 /* put reference to graph */
12118 r->rsprintf("<tr><td colspan=2><img src=\"%s\" usemap=\"#%s\"></tr>\n", ref.c_str(), hpanel);
12119 }
12120
12121 else if (equal_ustring(hgroup, "All")) {
12122 /* Display all panels */
12123 db_find_key(hDB, 0, "/History/Display", &hkey);
12124 if (hkey)
12125 for (i = 0, k = 0;; i++) { // scan Groups
12127
12128 if (!hkeyp)
12129 break;
12130
12131 db_get_key(hDB, hkeyp, &key);
12132
12133 char enc_group_name[256];
12136
12137 for (j = 0;; j++, k++) {
12138 // scan items
12140
12141 if (!hikeyp)
12142 break;
12143
12145
12146 char enc_panel_name[256];
12149
12150 std::string ref;
12151 ref += "graph.gif?width=Small";
12152 ref += "&cmd=oldhistory&group=";
12154 ref += "&panel=";
12156
12157 std::string ref2;
12158 ref2 += "?cmd=oldhistory&group=";
12160 ref2 += "&panel=";
12162
12163 if (endtime != 0) {
12164 char tmp[256];
12165 sprintf(tmp, "time=%s&scale=%d", time_to_string(endtime).c_str(), scale);
12166 ref += "&";
12167 ref += tmp;
12168 ref2 += "&";
12169 ref2 += tmp;
12170 }
12171
12172 if (k % 2 == 0)
12173 r->rsprintf("<tr><td><a href=\"%s\"><img src=\"%s\"></a>\n", ref2.c_str(), ref.c_str());
12174 else
12175 r->rsprintf("<td><a href=\"%s\"><img src=\"%s\"></a></tr>\n", ref2.c_str(), ref.c_str());
12176 } // items loop
12177 } // Groups loop
12178 } // All
12179 r->rsprintf("</table>\r\n");
12180 r->rsprintf("</div>\n"); // closing for <div id="mmain">
12181 r->rsprintf("</form>\n");
12182 r->rsprintf("</body></html>\r\n");
12183}
INT db_set_value_index(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT idx, DWORD type, BOOL trunc)
Definition odb.cxx:5365
void get_elog_url(char *url, int len)
void show_query_page(Param *p, Return *r)
Definition mhttpd.cxx:9791
std::string time_to_string(time_t t)
Definition mhttpd.cxx:8133
int get_hist_last_written(MVOdb *odb, const char *group, const char *panel, time_t endtime, int index, int want_all, time_t *plastwritten)
Definition mhttpd.cxx:8521
time_t string_to_time(const char *str)
Definition mhttpd.cxx:8117
void show_hist_config_page(MVOdb *odb, Param *p, Return *r, const char *hgroup, const char *hpanel)
Definition mhttpd.cxx:10519
void generate_hist_graph(MVOdb *odb, Return *rr, const char *hgroup, const char *hpanel, char *buffer, int *buffer_size, int width, int height, time_t xendtime, int scale, int index, int labels, const char *bgcolor, const char *fgcolor, const char *gridcolor)
Definition mhttpd.cxx:8604
void export_hist(MVOdb *odb, Return *r, const char *group, const char *panel, time_t endtime, int scale, int index, int labels)
Definition mhttpd.cxx:11025
#define M_MALLOC(x)
Definition midas.h:1552
#define M_FREE(x)
Definition midas.h:1554
#define write(n, a, f, d)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_navigation_bar()

void show_navigation_bar ( Return r,
const char cur_page 
)

Definition at line 1867 of file mhttpd.cxx.

1868{
1869 r->rsprintf("<script>\n");
1870 r->rsprintf("window.addEventListener(\"load\", function(e) { mhttpd_init('%s', 1000); });\n", cur_page);
1871 r->rsprintf("</script>\n");
1872
1873 r->rsprintf("<!-- header and side navigation will be filled in mhttpd_init -->\n");
1874 r->rsprintf("<div id=\"mheader\"></div>\n");
1875 r->rsprintf("<div id=\"msidenav\"></div>\n");
1876 r->rsprintf("<div id=\"mmain\">\n");
1877}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_odb_page()

void show_odb_page ( Param pp,
Return r,
const char dec_path,
int  write_access 
)

Definition at line 6793 of file mhttpd.cxx.

6794{
6795 int keyPresent, size, status, line, link_index;
6796 char colspan;
6797 char style[32];
6799 KEY key;
6800 DWORD delta;
6801
6803
6804 //printf("path [%s]\n", dec_path);
6805
6806 if (strcmp(dec_path, "root") == 0) {
6807 dec_path = "";
6808 }
6809
6810 char xdecpath[256];
6812 if (strrchr(xdecpath, '/'))
6813 mstrlcpy(xdecpath, strrchr(xdecpath, '/')+1, sizeof(xdecpath));
6814 if (xdecpath[0] == 0)
6815 mstrlcpy(xdecpath, "root", sizeof(xdecpath));
6816 show_header(r, "MIDAS online database", "", xdecpath, 0);
6817
6818 /* use javascript file */
6819 r->rsprintf("<script type=\"text/javascript\" src=\"midas.js\"></script>\n");
6820 r->rsprintf("<script type=\"text/javascript\" src=\"mhttpd.js\"></script>\n");
6821 r->rsprintf("<script type=\"text/javascript\" src=\"obsolete.js\"></script>\n");
6822 r->rsprintf("<script type=\"text/javascript\" src=\"controls.js\"></script>\n");
6823
6824 /* find key via path */
6826 if (status != DB_SUCCESS) {
6827 r->rsprintf("Error: cannot find key %s<P>\n", dec_path);
6828 r->rsprintf("</body></html>\r\n");
6829 return;
6830 }
6831
6832 char xdec_path[MAX_ODB_PATH];
6833
6834 /* if key is not of type TID_KEY, cut off key name */
6836 if (key.type != TID_KEY) {
6838
6839 /* strip variable name from path */
6840 char* p = xdec_path + strlen(xdec_path) - 1;
6841 while (*p && *p != '/')
6842 *p-- = 0;
6843 if (*p == '/')
6844 *p = 0;
6845
6847 if (status != DB_SUCCESS) {
6848 r->rsprintf("Error: cannot find key %s<P>\n", xdec_path);
6849 r->rsprintf("</body></html>\r\n");
6850 return;
6851 }
6852
6854 }
6855
6856 //mstrlcpy(enc_path, dec_path, enc_path_size);
6857 //urlEncode(enc_path, enc_path_size);
6858
6859 std::string odbpath = db_get_path(hDB, hkeyroot);
6860
6861 /*---- navigation bar ----*/
6862
6863 colspan = 7;
6864
6865 if (elog_mode) {
6866 r->rsprintf("<table class=\"mtableheader\">\n");
6867 r->rsprintf("<tr><td colspan=%d>\n", colspan);
6868 r->rsprintf("<input type=button value=ELog onclick=\"self.location=\'?cmd=Alarms\';\">\n");
6869 r->rsprintf("</td></tr></table>\n\n");
6870 } else
6871 show_navigation_bar(r, "ODB");
6872
6873 /*---- begin ODB directory table ----*/
6874
6875 r->rsprintf("<table class=\"mtable\" style=\"border-spacing:0px;\">\n");
6876 r->rsprintf("<tr><th colspan=%d class=\"mtableheader\">Online Database Browser</tr>\n", colspan);
6877 //buttons:
6878 if(!elog_mode){
6879 r->rsprintf("<tr><td colspan=%d>\n", colspan);
6880 r->rsprintf("<input type=button value=Find onclick=\"self.location=\'?cmd=Find\';\">\n");
6881 r->rsprintf("<input type=button value=Create onclick=\"dlgShow('dlgCreate')\">\n");
6882 r->rsprintf("<input type=button value=Link onclick=\"dlgShow('dlgLink')\">\n");
6883 r->rsprintf("<input type=button value=Delete onclick=\"dlgShow('dlgDelete')\">\n");
6884 r->rsprintf("<input type=button value=\"Create Elog from this page\" onclick=\"self.location=\'?cmd=Create Elog from this page&odb_path=%s\';\">\n", urlEncode(odbpath.c_str()).c_str());
6885 r->rsprintf("<input type=button value=\"Show open records\" onclick=\"self.location=\'?cmd=odb_sor&odb_path=%s\';\">\n", urlEncode(odbpath.c_str()).c_str());
6886 r->rsprintf("<input type=button value=\"Show ODB clients\" onclick=\"self.location=\'?cmd=odb_scl\';\">\n");
6887 r->rsprintf("</td></tr>\n");
6888 }
6889
6890 /*---- Build the Delete dialog------------------------------------*/
6891
6892 std::string dd = "";
6893
6894 dd += "<!-- Demo dialog -->\n";
6895 dd += "<div id=\"dlgDelete\" class=\"dlgFrame\">\n";
6896 dd += "<div class=\"dlgTitlebar\">Delete ODB entry</div>\n";
6897 dd += "<div class=\"dlgPanel\">\n";
6898 dd += "<div id=odbpath>";
6899 dd += "\"";
6900 dd += MJsonNode::Encode(odbpath.c_str());
6901 dd += "\"";
6902 dd += "</div>\n";
6903 dd += "<div><br></div>\n";
6904
6905 dd += "<table class=\"dialogTable\">\n";
6906 dd += "<th colspan=2>Delete ODB entries:</th>\n";
6907
6908 std::vector<std::string> delete_list;
6909
6910 int count_delete = 0;
6911
6912 /*---- ODB display -----------------------------------------------*/
6913
6914 /* display root key */
6915 r->rsprintf("<tr><td colspan=%d class='ODBpath'><b>", colspan);
6916 r->rsprintf("<a href=\"?cmd=oldodb\">/</a> \n");
6917
6918 std::string enc_root_path;
6919
6920 /*---- display path ----*/
6921 {
6922 const char* p = dec_path;
6923 while (*p) {
6924 std::string pd;
6925 while (*p && *p != '/')
6926 pd += *p++;
6927
6928 enc_root_path += urlEncode(pd.c_str());
6929
6930 if (pd.length() > 0)
6931 r->rsprintf("<a href=\"?cmd=oldodb&odb_path=%s\">%s</a>\n / ", enc_root_path.c_str(), pd.c_str());
6932
6933 enc_root_path += "/";
6934 if (*p == '/')
6935 p++;
6936 }
6937 }
6938
6939 r->rsprintf("</b></tr>\n");
6940
6941 /* enumerate subkeys */
6942 keyPresent = 0;
6943 for(int scan=0; scan<2; scan++){
6944 if(scan==1 && keyPresent==1) {
6945 r->rsprintf("<tr class=\"titleRow\">\n");
6946 r->rsprintf("<th class=\"ODBkey\">Key</th>\n");
6947 r->rsprintf("<th class=\"ODBvalue\">Value&nbsp;");
6948 r->rsprintf("<script type=\"text/javascript\">\n");
6949 r->rsprintf("function expand()\n");
6950 r->rsprintf("{\n");
6951 r->rsprintf(" var n = document.getElementsByName('ext');\n");
6952 r->rsprintf(" for (i=0 ; i<n.length ; i++) {\n");
6953 r->rsprintf(" if (n[i].style.display == 'none')\n");
6954 r->rsprintf(" n[i].style.display = 'table-cell';\n");
6955 r->rsprintf(" else\n");
6956 r->rsprintf(" n[i].style.display = 'none';\n");
6957 r->rsprintf(" }\n");
6958 r->rsprintf(" if (document.getElementById('expp').expflag === true) {\n");
6959 r->rsprintf(" document.getElementById('expp').expflag = false;\n");
6960 r->rsprintf(" document.getElementById('expp').innerHTML = '&#x21E5;';\n");
6961 r->rsprintf(" } else {\n");
6962 r->rsprintf(" document.getElementById('expp').expflag = true;\n");
6963 r->rsprintf(" document.getElementById('expp').innerHTML = '&#x21E4;';\n");
6964 r->rsprintf(" }\n");
6965 r->rsprintf("}\n");
6966 r->rsprintf("</script>");
6967 r->rsprintf("<div style=\"display:inline;float:right\"><a id=\"expp\"href=\"#\" onClick=\"expand();return false;\">&#x21E5;</div>");
6968 r->rsprintf("</th>\n");
6969 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Type</th>\n");
6970 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">#Val</th>\n");
6971 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Size</th>\n");
6972 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Written</th>\n");
6973 r->rsprintf("<th class=\"ODBvalue\" name=\"ext\" style=\"display:none\">Mode</th>\n");
6974 r->rsprintf("</tr>\n");
6975 }
6976 line = 0;
6977 for (int i = 0;; i++) {
6979 if (!hkey)
6980 break;
6981 db_get_link(hDB, hkey, &key);
6982
6983 if (scan == 0) {
6984 delete_list.push_back(key.name);
6985 }
6986
6987 if (line % 2 == 0)
6988 mstrlcpy(style, "ODBtableEven", sizeof(style));
6989 else
6990 mstrlcpy(style, "ODBtableOdd", sizeof(style));
6991
6992 std::string keyname = key.name;
6993 std::string enc_keyname = urlEncode(key.name);
6994
6995 std::string enc_full_path = enc_root_path + enc_keyname;
6996
6997 std::string odb_path = dec_path;
6998 if (odb_path.length() > 0 && odb_path[odb_path.length() - 1] != '/')
6999 odb_path += "/";
7000 odb_path += key.name;
7001
7002 /* resolve links */
7003 std::string enc_link_ref;
7004 char link_name[MAX_ODB_PATH];
7005 link_name[0] = 0;
7007 if (key.type == TID_LINK) {
7008 size = sizeof(link_name);
7010
7012
7013 if (status == DB_SUCCESS)
7014 db_get_key(hDB, hkey, &key);
7015
7016 //sprintf(link_ref, "?cmd=Set&odb_path=%s", full_path);
7017 enc_link_ref = "?cmd=Set&odb_path=";
7019
7020 if (status == DB_SUCCESS && link_name[0] == 0) {
7021 // fake the case when an empty link somehow resolves
7022 sprintf(link_name, "%s", "(empty)");
7023 }
7024 }
7025
7026 std::string enc_ref;
7027
7028 if (link_name[0]) {
7029 if (enc_root_path.back() == '/' && link_name[0] == '/') {
7030 //sprintf(ref, "?cmd=Set&odb_path=%s%s", root_path, link_name+1);
7031 enc_ref = "";
7032 enc_ref += "?cmd=Set&odb_path=";
7034 enc_ref += urlEncode(link_name + 1);
7035 } else {
7036 //sprintf(ref, "?cmd=Set&odb_path=%s%s", root_path, link_name);
7037 enc_ref = "";
7038 enc_ref += "?cmd=Set&odb_path=";
7041 }
7042 } else {
7043 //sprintf(ref, "?cmd=Set&odb_path=%s", full_path);
7044 enc_ref = "";
7045 enc_ref += "?cmd=Set&odb_path=";
7047 }
7048
7049 if (status != DB_SUCCESS) {
7050 if (scan == 1) {
7051 r->rsprintf("<tr><td class=\"yellowLight\">");
7052 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td><b><div style=\"color:red\">&lt;cannot resolve link&gt;</div></b></tr>\n", keyname.c_str(), enc_link_ref.c_str(), link_name[0]?link_name:"(empty)");
7053 }
7054 } else {
7055
7056 if (key.type == TID_KEY && scan == 0) {
7057 /* for keys, don't display data value */
7058 r->rsprintf("<tr><td colspan=%d class=\"ODBdirectory\"><a href=\"?cmd=oldodb&odb_path=%s\">&#x25B6 %s</a>\n", colspan, enc_full_path.c_str(), keyname.c_str());
7059 if (link_name[0])
7060 r->rsprintf("<i>&rarr; <a href=\"%s\">%s</a></i>", enc_link_ref.c_str(), link_name);
7061 r->rsprintf("</tr>\n");
7062 } else if(key.type != TID_KEY && scan == 1) {
7063
7064 if (strchr(link_name, '['))
7065 link_index = atoi(strchr(link_name, '[')+1);
7066 else
7067 link_index = -1;
7068
7069 /* display single value */
7070 if (key.num_values == 1 || link_index != -1) {
7071 char data[TEXT_SIZE];
7072 size = sizeof(data);
7073 db_get_data(hDB, hkey, data, &size, key.type);
7074
7075 std::string data_str;
7076
7077 if (link_index != -1)
7079 else
7081
7082 if (key.type == TID_STRING) {
7083 if (size == sizeof(data)) {
7084 data_str += "...(truncated)";
7085 }
7086 }
7087
7088 std::string hex_str;
7089
7090 if (key.type != TID_STRING) {
7091 if (link_index != -1)
7093 else
7095 }
7096
7097 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
7098 data_str = "(empty)";
7099 hex_str = "";
7100 }
7101
7102 r->rsprintf("<tr>\n");
7103 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
7104 if (link_name[0]) {
7105 r->rsprintf("<td class=\"ODBkey\">\n");
7106 r->rsprintf("%s <i>&rarr; ", keyname.c_str());
7107 r->rsprintf("<a href=\"%s\">%s</a></i>\n", enc_link_ref.c_str(), link_name);
7108 r->rsprintf("<td class=\"%s\">\n", style);
7109 if (!write_access)
7110 r->rsprintf("%s (%s)", data_str.c_str(), hex_str.c_str());
7111 else {
7112 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7113 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">%s (%s)</a>\n", odb_path.c_str(), data_str.c_str(), hex_str.c_str());
7114 }
7115 } else {
7116 r->rsprintf("<td class=\"ODBkey\">\n");
7117 r->rsprintf("%s<td class=\"%s\">", keyname.c_str(), style);
7118 if (!write_access)
7119 r->rsprintf("%s (%s)", data_str.c_str(), hex_str.c_str());
7120 else {
7121 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7122 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">%s (%s)</a>\n", odb_path.c_str(), data_str.c_str(), hex_str.c_str());
7123 }
7124 }
7125 } else {
7126 if (strchr(data_str.c_str(), '\n')) {
7127 if (link_name[0]) {
7128 r->rsprintf("<td class=\"ODBkey\">");
7129 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td class=\"ODBvalue\">", keyname.c_str(), enc_link_ref.c_str(), link_name);
7130 } else
7131 r->rsprintf("<td class=\"ODBkey\">%s<td class=\"%s\">", keyname.c_str(), style);
7132 r->rsprintf("\n<pre>");
7133 strencode3(r, data_str.c_str());
7134 r->rsprintf("</pre>");
7135 if (strlen(data) > data_str.length())
7136 r->rsprintf("<i>... (%d bytes total)<p>\n", (int)strlen(data));
7137
7138 r->rsprintf("<a href=\"%s\">Edit</a>\n", enc_ref.c_str());
7139 } else {
7140 if (link_name[0]) {
7141 r->rsprintf("<td class=\"ODBkey\">\n");
7142 r->rsprintf("%s <i>&rarr; <a href=\"%s\">%s</a></i><td class=\"%s\">", keyname.c_str(), enc_link_ref.c_str(), link_name, style);
7143 if (!write_access)
7144 strencode(r, data_str.c_str());
7145 else {
7146 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7147 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", odb_path.c_str());
7148 strencode(r, data_str.c_str());
7149 r->rsprintf("</a>\n");
7150 }
7151 } else {
7152 r->rsprintf("<td class=\"ODBkey\">%s<td class=\"%s\">", keyname.c_str(), style);
7153 if (!write_access) {
7154 strencode(r, data_str.c_str());
7155 } else {
7156 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), odb_path.c_str());
7157 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", odb_path.c_str());
7158 strencode(r, data_str.c_str());
7159 r->rsprintf("</a>\n");
7160 }
7161 }
7162 }
7163 }
7164
7165 /* extended key information */
7166 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7167 r->rsprintf("%s", rpc_tid_name(key.type));
7168 r->rsprintf("</td>\n");
7169
7170 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7171 r->rsprintf("%d", key.num_values);
7172 r->rsprintf("</td>\n");
7173
7174 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7175 r->rsprintf("%d", key.item_size);
7176 r->rsprintf("</td>\n");
7177
7178 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7180 if (delta < 60)
7181 r->rsprintf("%ds", delta);
7182 else if (delta < 3600)
7183 r->rsprintf("%1.0lfm", delta / 60.0);
7184 else if (delta < 86400)
7185 r->rsprintf("%1.0lfh", delta / 3600.0);
7186 else if (delta < 86400 * 99)
7187 r->rsprintf("%1.0lfd", delta / 86400.0);
7188 else
7189 r->rsprintf(">99d");
7190 r->rsprintf("</td>\n");
7191
7192 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\">");
7194 r->rsprintf("R");
7196 r->rsprintf("W");
7198 r->rsprintf("D");
7200 r->rsprintf("E");
7201 r->rsprintf("</td>\n");
7202
7203 line++;
7204 r->rsprintf("</tr>\n");
7205 } else { /* display array value */
7206 /* check for exceeding length */
7207 if (key.num_values > 1000 && !pp->isparam("all"))
7208 r->rsprintf("<tr><td class=\"ODBkey\">%s<td class=\"%s\"><span style=\"font-style: italic\"><a href=\"?cmd=oldodb&odb_path=%s&all=1\">... %d values ...</a></span>\n", keyname.c_str(), style, enc_full_path.c_str(), key.num_values);
7209 else {
7210 /* display first value */
7211 if (link_name[0])
7212 r->rsprintf("<tr><td class=\"ODBkey\" rowspan=%d>%s<br><i>&rarr; <a href=\"%s\">%s</a></i>\n", key.num_values, keyname.c_str(), enc_link_ref.c_str(), link_name);
7213 else
7214 r->rsprintf("<tr><td class=\"ODBkey\" rowspan=%d>%s\n", key.num_values, keyname.c_str());
7215
7216 for (int j = 0; j < key.num_values; j++) {
7217 if (line % 2 == 0)
7218 mstrlcpy(style, "ODBtableEven", sizeof(style));
7219 else
7220 mstrlcpy(style, "ODBtableOdd", sizeof(style));
7221
7222 char data[TEXT_SIZE];
7223 size = sizeof(data);
7224 db_get_data_index(hDB, hkey, data, &size, j, key.type);
7225 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
7226
7227 std::string hex_str;
7228 if (key.type == TID_STRING || key.type == TID_LINK) {
7229 hex_str = "";
7230 } else {
7232 }
7233
7234 if (key.type == TID_STRING) {
7235 if (size == sizeof(data)) {
7236 data_str += "...(truncated)";
7237 }
7238 }
7239
7240 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
7241 data_str = "(empty)";
7242 hex_str = "";
7243 }
7244
7245 //sprintf(ref, "?cmd=Set&odb_path=%s&index=%d", full_path, j);
7246 enc_ref = "";
7247 enc_ref += "?cmd=Set&odb_path=";
7249 enc_ref += "&index=";
7250 enc_ref += toString(j);
7251
7252 std::string tmpstr;
7253 //sprintf(str, "%s[%d]", odb_path, j);
7254 tmpstr += odb_path;
7255 tmpstr += "[";
7256 tmpstr += toString(j);
7257 tmpstr += "]";
7258
7259 if (j > 0)
7260 r->rsprintf("<tr>");
7261
7262 r->rsprintf("<td class=\"%s\">[%d]&nbsp;", style, j);
7263 if (!write_access)
7264 r->rsprintf("<a href=\"%s\">", enc_ref.c_str());
7265 else {
7266 r->rsprintf("<a href=\"%s\" onClick=\"ODBInlineEdit(this.parentNode,\'%s\');return false;\" ", enc_ref.c_str(), tmpstr.c_str());
7267 r->rsprintf("onFocus=\"ODBInlineEdit(this.parentNode,\'%s\');\">", tmpstr.c_str());
7268 }
7269 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0])
7270 r->rsprintf("%s (%s)</a>\n", data_str.c_str(), hex_str.c_str());
7271 else
7272 r->rsprintf("%s</a>\n", data_str.c_str());
7273
7274 if (j == 0) {
7275 /* extended key information */
7276 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7277 r->rsprintf("%s", rpc_tid_name(key.type));
7278 r->rsprintf("</td>\n");
7279
7280 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7281 r->rsprintf("%d", key.num_values);
7282 r->rsprintf("</td>\n");
7283
7284 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7285 r->rsprintf("%d", key.item_size);
7286 r->rsprintf("</td>\n");
7287
7288 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7290 if (delta < 60)
7291 r->rsprintf("%ds", delta);
7292 else if (delta < 3600)
7293 r->rsprintf("%1.0lfm", delta / 60.0);
7294 else if (delta < 86400)
7295 r->rsprintf("%1.0lfh", delta / 3600.0);
7296 else if (delta < 86400 * 99)
7297 r->rsprintf("%1.0lfh", delta / 86400.0);
7298 else
7299 r->rsprintf(">99d");
7300 r->rsprintf("</td>\n");
7301
7302 r->rsprintf("<td class=\"ODBkey\" name=\"ext\" style=\"display:none\" rowspan=%d>", key.num_values);
7304 r->rsprintf("R");
7306 r->rsprintf("W");
7308 r->rsprintf("D");
7310 r->rsprintf("E");
7311 r->rsprintf("</td>\n");
7312 }
7313 line++;
7314 }
7315
7316 r->rsprintf("</tr>\n");
7317 }
7318 }
7319 } else if(key.type != TID_KEY){
7320 keyPresent = 1; //flag that we've seen a key on the first pass, and should therefore write the Key / Value headline
7321 }
7322 }
7323 }
7324 }
7325 r->rsprintf("</table>\n");
7326 r->rsprintf("</div>\n"); // <div id="mmain">
7327
7328 /*---- Build the Delete dialog------------------------------------*/
7329
7330 std::sort(delete_list.begin(), delete_list.end());
7331
7332 for (unsigned i=0; i<delete_list.size(); i++) {
7333 std::string name = delete_list[i];
7334
7335 dd += "<tr><td style=\"text-align:left;\" align=left><input align=left type=checkbox id=delete";
7336 dd += toString(count_delete++);
7337 dd += " value=\'";
7338 dd += "\"";
7339 dd += MJsonNode::Encode(name.c_str());
7340 dd += "\"";
7341 dd += "\'>";
7342 dd += name;
7343 dd += "</input></td></tr>\n";
7344 }
7345
7346 dd += "</table>\n";
7347 dd += "<input type=button value=Delete onClick='mhttpd_delete_page_handle_delete(event);'>\n";
7348 dd += "<input type=button value=Cancel onClick='mhttpd_delete_page_handle_cancel(event);'>\n";
7349 dd += "</div>\n";
7350 dd += "</div>\n";
7351
7352 r->rsputs(dd.c_str());
7353
7354 /*---- Build the Create dialog------------------------------------*/
7355
7356 std::string cd = "";
7357
7358 cd += "<!-- Demo dialog -->\n";
7359 cd += "<div id=\"dlgCreate\" class=\"dlgFrame\">\n";
7360 cd += "<div class=\"dlgTitlebar\">Create ODB entry</div>\n";
7361 cd += "<div class=\"dlgPanel\">\n";
7362 cd += "<br />\n";
7363 cd += "<div id=odbpath>";
7364 cd += "\"";
7365 cd += MJsonNode::Encode(odbpath.c_str());
7366 cd += "\"";
7367 cd += "</div>\n";
7368 cd += "<div><br></div>\n";
7369
7370 cd += "<table class=\"dialogTable\">\n";
7371 cd += "<th colspan=2>Create ODB entry:</th>\n";
7372 cd += "<tr>";
7373 cd += "<td>Type";
7374 cd += "<td>";
7375 cd += "<select type=text size=1 id=create_tid name=type>";
7376 cd += "<option value=7>Integer (32-bit)";
7377 cd += "<option value=9>Float (4 Bytes)";
7378 cd += "<option value=12>String";
7379 cd += "<option selected value=15>Subdirectory";
7380 cd += "<option value=1>Byte";
7381 cd += "<option value=2>Signed byte";
7382 cd += "<option value=3>Character (8-bit)";
7383 cd += "<option value=4>Word (16-bit)";
7384 cd += "<option value=5>Short integer (16-bit)";
7385 cd += "<option value=6>Double Word (32-bit)";
7386 cd += "<option value=8>Boolean";
7387 cd += "<option value=10>Double float (8 Bytes)";
7388 //cd += "<option value=16>Symbolic link";
7389 cd += "</select>";
7390 cd += "</tr>\n";
7391 cd += "<tr><td>Name<td><input type=text size=31 maxlength=31 id=create_name name=value></tr>\n";
7392 cd += "<tr><td>Array size<td><input type=text size=31 maxlength=31 id=create_array_length name=index value=1></tr>\n";
7393 cd += "<tr><td>String length<td><input type=text size=31 maxlength=31 id=create_strlen name=strlen value=32></tr>\n";
7394 cd += "</table>\n";
7395 cd += "<input type=button value=Create onClick='mhttpd_create_page_handle_create(event);'>\n";
7396 cd += "<input type=button value=Cancel onClick='mhttpd_create_page_handle_cancel(event);'>\n";
7397 cd += "</div>\n";
7398 cd += "</div>\n";
7399
7400 r->rsputs(cd.c_str());
7401
7402 /*---- Build the Link dialog------------------------------------*/
7403
7404 std::string ld = "";
7405
7406 ld += "<!-- Demo dialog -->\n";
7407 ld += "<div id=\"dlgLink\" class=\"dlgFrame\">\n";
7408 ld += "<div class=\"dlgTitlebar\">Create a link to an ODB entry</div>\n";
7409 ld += "<div class=\"dlgPanel\">\n";
7410 ld += "<br />\n";
7411 ld += "<div id=link_odbpath>";
7412 ld += "\"";
7413 ld += MJsonNode::Encode(odbpath.c_str());
7414 ld += "\"";
7415 ld += "</div>\n";
7416 ld += "<div><br></div>\n";
7417
7418 ld += "<table class=\"dialogTable\">\n";
7419 ld += "<th colspan=2>Create a link to an ODB entry:</th>\n";
7420 ld += "<tr><td>Name<td><input type=text size=31 maxlength=31 id=link_name name=value></tr>\n";
7421 ld += "<tr><td>Link target<td><input type=text size=31 maxlength=256 id=link_target name=target></tr>\n";
7422 ld += "</table>\n";
7423 ld += "<input type=button value=Link onClick='mhttpd_link_page_handle_link(event);'>\n";
7424 ld += "<input type=button value=Cancel onClick='mhttpd_link_page_handle_cancel(event);'>\n";
7425 ld += "</div>\n";
7426 ld += "</div>\n";
7427
7428 r->rsputs(ld.c_str());
7429}
#define MODE_EXCLUSIVE
Definition midas.h:373
#define MODE_DELETE
Definition midas.h:372
#define MODE_WRITE
Definition midas.h:371
#define MODE_READ
Definition midas.h:370
INT db_get_link(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6072
INT db_get_link_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6656
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition odb.cxx:6132
void strencode(Return *r, const char *text)
Definition mhttpd.cxx:2019
void strencode3(Return *r, const char *text)
Definition mhttpd.cxx:2078
WORD access_mode
Definition midas.h:1033
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_odb_tag()

void show_odb_tag ( Param pp,
Return r,
const char path,
const char keypath1,
const char format,
int  n_var,
int  edit,
char type,
char pwd,
char tail 
)

Definition at line 3275 of file mhttpd.cxx.

3276{
3277 int size, index, i_edit, i_set;
3278 char data[TEXT_SIZE], full_keypath[256], keypath[256], *p;
3279 HNDLE hDB, hkey;
3280 KEY key;
3281
3282 /* check if variable to edit */
3283 i_edit = -1;
3284 if (equal_ustring(pp->getparam("cmd"), "Edit"))
3285 i_edit = atoi(pp->getparam("index"));
3286
3287 /* check if variable to set */
3288 i_set = -1;
3289 if (equal_ustring(pp->getparam("cmd"), "Set"))
3290 i_set = atoi(pp->getparam("index"));
3291
3292 /* check if path contains index */
3294 mstrlcpy(keypath, keypath1, sizeof(keypath));
3295 index = 0;
3296
3297 if (strchr(keypath, '[') && strchr(keypath, ']')) {
3298 for (p = strchr(keypath, '[') + 1; *p && *p != ']'; p++)
3299 if (!isdigit(*p))
3300 break;
3301
3302 if (*p && *p == ']') {
3303 index = atoi(strchr(keypath, '[') + 1);
3304 *strchr(keypath, '[') = 0;
3305 }
3306 }
3307
3309 db_find_key(hDB, 0, keypath, &hkey);
3310 if (!hkey)
3311 r->rsprintf("<b>Key \"%s\" not found in ODB</b>\n", keypath);
3312 else {
3313 db_get_key(hDB, hkey, &key);
3314 size = sizeof(data);
3316
3317 std::string data_str;
3318 if (format && strlen(format)>0)
3319 data_str = db_sprintff(format, data, key.item_size, 0, key.type);
3320 else
3322
3323 if (equal_ustring(type, "checkbox")) {
3324
3325 if (pp->isparam("cbi"))
3326 i_set = atoi(pp->getparam("cbi"));
3327 if (n_var == i_set) {
3328 /* toggle state */
3329 if (key.type == TID_BOOL) {
3330 if (data_str[0] == 'y')
3331 data_str = "n";
3332 else
3333 data_str = "y";
3334 } else {
3335 if (atoi(data_str.c_str()) > 0)
3336 data_str = "0";
3337 else
3338 data_str = "1";
3339 }
3340
3341 db_sscanf(data_str.c_str(), data, &size, 0, key.type);
3343 }
3344
3345 std::string options;
3346 if (data_str[0] == 'y' || atoi(data_str.c_str()) > 0)
3347 options += "checked ";
3348 if (!edit)
3349 options += "disabled ";
3350 else {
3351 if (edit == 1) {
3352 options += "onClick=\"o=document.createElement('input');o.type='hidden';o.name='cbi';o.value='";
3353 options += msprintf("%d", n_var);
3354 options += "';document.form1.appendChild(o);";
3355 options += "document.form1.submit();\" ";
3356 }
3357 }
3358
3359 if (tail[0])
3360 options += tail;
3361
3362 r->rsprintf("<input type=\"checkbox\" %s>\n", options.c_str());
3363
3364 } else { // checkbox
3365
3366 if (edit == 1) {
3367 if (n_var == i_set) {
3368 /* set value */
3369 char str[256];
3370 mstrlcpy(str, pp->getparam("value"), sizeof(str));
3371 db_sscanf(str, data, &size, 0, key.type);
3373
3374 /* read back value */
3375 size = sizeof(data);
3378 }
3379
3380 if (n_var == i_edit) {
3381 r->rsprintf("<input type=text size=10 maxlength=80 name=value value=\"%s\">\n", data_str.c_str());
3382 r->rsprintf("<input type=submit size=20 name=cmd value=Set>\n");
3383 r->rsprintf("<input type=hidden name=index value=%d>\n", n_var);
3384 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
3385 } else {
3386 if (edit == 2) {
3387 /* edit handling through user supplied JavaScript */
3388 r->rsprintf("<a href=\"#\" %s>", tail);
3389 } else {
3390 /* edit handling through form submission */
3391 if (pwd[0]) {
3392 r->rsprintf("<a onClick=\"promptpwd('%s?cmd=Edit&index=%d&pnam=%s')\" href=\"#\">", path, n_var, pwd);
3393 } else {
3394 r->rsprintf("<a href=\"%s?cmd=Edit&index=%d\" %s>", path, n_var, tail);
3395 }
3396 }
3397
3398 r->rsputs(data_str.c_str());
3399 r->rsprintf("</a>");
3400 }
3401 } else if (edit == 2) {
3402 r->rsprintf("<a href=\"#\" onclick=\"ODBEdit('%s')\">\n", full_keypath);
3403 r->rsputs(data_str.c_str());
3404 r->rsprintf("</a>");
3405 }
3406 else
3407 r->rsputs(data_str.c_str());
3408 }
3409 }
3410}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_password_page()

void show_password_page ( Return r,
const char dec_path,
const char password 
)

Definition at line 6702 of file mhttpd.cxx.

6703{
6704 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6705 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6706 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6707
6708 r->rsprintf("<html><head>\n");
6709 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6710 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6711 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6712 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6713
6714 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6715
6716 /*---- page header ----*/
6717 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6718
6719 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6720 if (password[0])
6721 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6722
6723 r->rsprintf("<tr><th>Please enter password</tr>\n");
6724 r->rsprintf("<tr><td align=center><input type=password name=pwd></tr>\n");
6725 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6726
6727 r->rsprintf("</table>\n");
6728
6729 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6730 r->rsprintf("</form>\n");
6731 r->rsprintf("</body></html>\r\n");
6732}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_query_page()

void show_query_page ( Param p,
Return r 
)

Definition at line 9791 of file mhttpd.cxx.

9792{
9793 int i;
9794 HNDLE hDB;
9795
9796 if (p->getparam("m1") && *p->getparam("m1")) {
9797 struct tm tms;
9798 memset(&tms, 0, sizeof(struct tm));
9799
9800 tms.tm_year = atoi(p->getparam("y1")) % 100;
9801
9802 std::string m1 = p->getparam("m1");
9803 for (i = 0; i < 12; i++)
9804 if (equal_ustring(m1.c_str(), mname[i]))
9805 break;
9806 if (i == 12)
9807 i = 0;
9808
9809 tms.tm_mon = i;
9810 tms.tm_mday = atoi(p->getparam("d1"));
9811 tms.tm_hour = atoi(p->getparam("h1"));
9812
9813 if (tms.tm_year < 90)
9814 tms.tm_year += 100;
9815
9817
9818 memset(&tms, 0, sizeof(struct tm));
9819 tms.tm_year = atoi(p->getparam("y2")) % 100;
9820
9821 std::string m2 = p->getparam("m2");
9822 for (i = 0; i < 12; i++)
9823 if (equal_ustring(m2.c_str(), mname[i]))
9824 break;
9825 if (i == 12)
9826 i = 0;
9827
9828 tms.tm_mon = i;
9829 tms.tm_mday = atoi(p->getparam("d2"));
9830 tms.tm_hour = atoi(p->getparam("h2"));
9831
9832 if (tms.tm_year < 90)
9833 tms.tm_year += 100;
9834
9836
9837 if (ltime_end == ltime_start)
9838 ltime_end += 3600 * 24;
9839
9840 std::string redir;
9841 redir += "?cmd=oldhistory&";
9842 redir += add_param_to_url("group", p->getparam("group"));
9843 redir += "&";
9844 redir += add_param_to_url("panel", p->getparam("panel"));
9845 redir += "&";
9846 redir += add_param_to_url("scale", toString((int)(ltime_end - ltime_start)).c_str());
9847 redir += "&";
9849 if (p->isparam("hindex")) {
9850 redir += "&";
9851 redir += add_param_to_url("index", p->getparam("hindex"));
9852 }
9853 redirect(r, redir.c_str());
9854 return;
9855 }
9856
9858 show_header(r, "History", "GET", "", 0);
9859
9860 /* set the times */
9861
9862 time_t now = time(NULL);
9863
9864 time_t starttime = now - 3600 * 24;
9865 time_t endtime = now;
9866 bool full_day = true;
9867
9868 if (p->isparam("htime")) {
9869 endtime = string_to_time(p->getparam("htime"));
9870
9871 if (p->isparam("hscale")) {
9872 starttime = endtime - atoi(p->getparam("hscale"));
9873 full_day = false;
9874 } else {
9875 starttime = endtime - 3600 * 24;
9876 full_day = false;
9877 }
9878 }
9879
9880 /* menu buttons */
9881 r->rsprintf("<tr><td colspan=2>\n");
9882 r->rsprintf("<input type=hidden name=cmd value=OldHistory>\n");
9883 r->rsprintf("<input type=submit name=hcmd value=Query>\n");
9884 r->rsprintf("<input type=submit name=hcmd value=Cancel>\n");
9885 if (p->isparam("group"))
9886 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", p->getparam("group"));
9887 if (p->isparam("panel"))
9888 r->rsprintf("<input type=hidden name=panel value=\"%s\">\n", p->getparam("panel"));
9889 if (p->isparam("htime"))
9890 r->rsprintf("<input type=hidden name=htime value=\"%s\">\n", p->getparam("htime"));
9891 if (p->isparam("hscale"))
9892 r->rsprintf("<input type=hidden name=hscale value=\"%s\">\n", p->getparam("hscale"));
9893 if (p->isparam("hindex"))
9894 r->rsprintf("<input type=hidden name=hindex value=\"%s\">\n", p->getparam("hindex"));
9895 r->rsprintf("</tr>\n\n");
9896 r->rsprintf("</table>"); //end header
9897
9898 r->rsprintf("<table class=\"dialogTable\">"); //main table
9899
9900 struct tm tms;
9902 tms.tm_year += 1900;
9903
9904 r->rsprintf("<tr><td nowrap>Start date:</td>");
9905
9906 r->rsprintf("<td>Month: <select name=\"m1\">\n");
9907 r->rsprintf("<option value=\"\">\n");
9908 for (i = 0; i < 12; i++)
9909 if (i == tms.tm_mon)
9910 r->rsprintf("<option selected value=\"%s\">%s\n", mname[i], mname[i]);
9911 else
9912 r->rsprintf("<option value=\"%s\">%s\n", mname[i], mname[i]);
9913 r->rsprintf("</select>\n");
9914
9915 r->rsprintf("&nbsp;Day: <select name=\"d1\">");
9916 r->rsprintf("<option selected value=\"\">\n");
9917 for (i = 0; i < 31; i++)
9918 if (i + 1 == tms.tm_mday)
9919 r->rsprintf("<option selected value=%d>%d\n", i + 1, i + 1);
9920 else
9921 r->rsprintf("<option value=%d>%d\n", i + 1, i + 1);
9922 r->rsprintf("</select>\n");
9923
9924 int start_hour = tms.tm_hour;
9925 if (full_day)
9926 start_hour = 0;
9927
9928 r->rsprintf("&nbsp;Hour: <input type=\"text\" size=5 maxlength=5 name=\"h1\" value=\"%d\">", start_hour);
9929
9930 r->rsprintf("&nbsp;Year: <input type=\"text\" size=5 maxlength=5 name=\"y1\" value=\"%d\">", tms.tm_year);
9931 r->rsprintf("</td></tr>\n");
9932
9933 r->rsprintf("<tr><td nowrap>End date:</td>");
9934
9936 tms.tm_year += 1900;
9937
9938 r->rsprintf("<td>Month: <select name=\"m2\">\n");
9939 r->rsprintf("<option value=\"\">\n");
9940 for (i = 0; i < 12; i++)
9941 if (i == tms.tm_mon)
9942 r->rsprintf("<option selected value=\"%s\">%s\n", mname[i], mname[i]);
9943 else
9944 r->rsprintf("<option value=\"%s\">%s\n", mname[i], mname[i]);
9945 r->rsprintf("</select>\n");
9946
9947 r->rsprintf("&nbsp;Day: <select name=\"d2\">");
9948 r->rsprintf("<option selected value=\"\">\n");
9949 for (i = 0; i < 31; i++)
9950 if (i + 1 == tms.tm_mday)
9951 r->rsprintf("<option selected value=%d>%d\n", i + 1, i + 1);
9952 else
9953 r->rsprintf("<option value=%d>%d\n", i + 1, i + 1);
9954 r->rsprintf("</select>\n");
9955
9956 int end_hour = tms.tm_hour;
9957 if (full_day)
9958 end_hour = 24;
9959
9960 r->rsprintf("&nbsp;Hour: <input type=\"text\" size=5 maxlength=5 name=\"h2\" value=\"%d\">", end_hour);
9961
9962 r->rsprintf("&nbsp;Year: <input type=\"text\" size=5 maxlength=5 name=\"y2\" value=\"%d\">", tms.tm_year);
9963 r->rsprintf("</td></tr>\n");
9964
9965 r->rsprintf("</table>\n");
9966 r->rsprintf("</div>\n"); // closing for <div id="mmain">
9967 r->rsprintf("</form>\n");
9968 r->rsprintf("</body></html>\r\n");
9969}
time_t mktime_with_dst(const struct tm *ptms)
Definition mhttpd.cxx:9745
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_set_page()

void show_set_page ( Param pp,
Return r,
const char group,
int  index,
const char value 
)

Definition at line 7433 of file mhttpd.cxx.

7436{
7437 int status, size;
7438 HNDLE hDB, hkey;
7439 KEY key;
7440 char data[TEXT_SIZE];
7441
7442 std::string odb_path = pp->getparam("odb_path");
7443
7444 //printf("show_set_page: odb_path [%s] group [%s] index %d value [%s]\n", odb_path.c_str(), group, index, value);
7445
7447
7448 /* show set page if no value is given */
7449 if (!pp->isparam("value") && !*pp->getparam("text")) {
7450 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7451 if (status != DB_SUCCESS) {
7452 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7453 return;
7454 }
7455 db_get_link(hDB, hkey, &key);
7456
7457 show_header(r, "Set value", "POST", "", 0);
7458 //close header:
7459 r->rsprintf("</table>");
7460
7461 //main table:
7462 r->rsprintf("<table class=\"dialogTable\">");
7463
7464 if (index > 0)
7465 r->rsprintf("<input type=hidden name=index value=\"%d\">\n", index);
7466 else
7467 index = 0;
7468
7469 if (group[0])
7470 r->rsprintf("<input type=hidden name=group value=\"%s\">\n", group);
7471
7472 r->rsprintf("<input type=hidden name=odb_path value=\"%s\">\n", odb_path.c_str());
7473
7474 std::string data_str1 = rpc_tid_name(key.type);
7475 std::string str1;
7476 if (key.num_values > 1) {
7477 data_str1 += msprintf("[%d]", key.num_values);
7478 str1 = msprintf("%s[%d]", odb_path.c_str(), index);
7479 } else
7480 str1 = odb_path.c_str();
7481
7482 r->rsprintf("<tr><th colspan=2>Set new value - type = %s</tr>\n", data_str1.c_str());
7483 r->rsprintf("<tr><td>%s<td>\n", str1.c_str());
7484
7485 /* set current value as default */
7486 size = sizeof(data);
7487 db_get_link_data(hDB, hkey, data, &size, key.type);
7488 std::string data_str = db_sprintf(data, key.item_size, index, key.type);
7489
7490 if (equal_ustring(data_str.c_str(), "<NULL>"))
7491 data_str = "";
7492
7493 if (strchr(data_str.c_str(), '\n') != NULL) {
7494 r->rsprintf("<textarea rows=20 cols=80 name=\"text\">\n");
7495 strencode3(r, data);
7496 r->rsprintf("</textarea>\n");
7497 } else {
7498 size = 20;
7499 if ((int) data_str.length() > size)
7500 size = data_str.length() + 3;
7501 if (size > 80)
7502 size = 80;
7503
7504 r->rsprintf("<input type=\"text\" size=%d maxlength=256 name=\"value\" value=\"", size);
7505 strencode(r, data_str.c_str());
7506 r->rsprintf("\">\n");
7507 }
7508
7509 r->rsprintf("</tr>\n");
7510
7511 r->rsprintf("<tr><td align=center colspan=2>");
7512 r->rsprintf("<input type=submit name=cmd value=Set>");
7513 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7514 r->rsprintf("</tr>");
7515 r->rsprintf("</table>");
7516
7517 r->rsprintf("<input type=hidden name=cmd value=Set>\n");
7518
7519 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7520 r->rsprintf("</form>\n");
7521 r->rsprintf("</body></html>\r\n");
7522 return;
7523 } else {
7524 /* set value */
7525
7526 status = db_find_link(hDB, 0, odb_path.c_str(), &hkey);
7527 if (status != DB_SUCCESS) {
7528 r->rsprintf("Error: cannot find key %s<P>\n", odb_path.c_str());
7529 return;
7530 }
7531 db_get_link(hDB, hkey, &key);
7532
7533 memset(data, 0, sizeof(data));
7534
7535 if (pp->getparam("text") && *pp->getparam("text"))
7536 mstrlcpy(data, pp->getparam("text"), sizeof(data));
7537 else
7538 db_sscanf(value, data, &size, 0, key.type);
7539
7540 if (index < 0)
7541 index = 0;
7542
7543 /* extend data size for single string if necessary */
7544 if ((key.type == TID_STRING || key.type == TID_LINK)
7545 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1)
7546 key.item_size = strlen(data) + 1;
7547
7548 if (key.item_size == 0)
7550
7551 if (key.num_values > 1)
7553 else
7555
7556 if (status == DB_NO_ACCESS)
7557 r->rsprintf("<h2>Write access not allowed</h2>\n");
7558
7559 redirect(r, "");
7560
7561 return;
7562 }
7563}
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7425
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7754
Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_text_header()

void show_text_header ( Return r)

Definition at line 1827 of file mhttpd.cxx.

1828{
1829 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1830 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1831 r->rsprintf("Access-Control-Allow-Origin: *\r\n");
1832 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1833 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1834 r->rsprintf("Content-Type: text/plain; charset=%s\r\n\r\n", HTTP_ENCODING);
1835}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SortHistPlotVars()

static void SortHistPlotVars ( HistPlot hp)
static

Definition at line 10498 of file mhttpd.cxx.

10499{
10500 /* sort variables according to "hist_order" */
10501
10502 bool need_sort = false;
10503 for (size_t i=1; i<hp.vars.size(); i++) {
10504 if (hp.vars[i-1].order >= hp.vars[i].order) {
10505 need_sort = true;
10506 }
10507 }
10508
10509 if (need_sort) {
10510 /* sort variables by order */
10511 std::sort(hp.vars.begin(), hp.vars.end(), cmp_vars);
10512
10513 /* renumber the variables according to the new sorted order */
10514 for (size_t index=0; index<hp.vars.size(); index++)
10515 hp.vars[index].order = (index+1)*10;
10516 }
10517}
static bool cmp_vars(const HistVar &a, const HistVar &b)
Definition mhttpd.cxx:10101
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SplitEventAndTagNames()

static void SplitEventAndTagNames ( std::string  var_name,
std::string &  event_name,
std::string &  tag_name 
)
static

Definition at line 10151 of file mhttpd.cxx.

10151 {
10152 event_name = "";
10153 tag_name = "";
10154
10155 std::vector<size_t> colons;
10156
10157 for (size_t i = 0; i < var_name.size(); i++) {
10158 if (var_name[i] == ':') {
10159 colons.push_back(i);
10160 }
10161 }
10162
10163 if (colons.size() == 0) {
10164 // No colons - leave the tag name empty
10165 event_name = var_name;
10166 } else {
10167 size_t split_pos;
10168 size_t slash_pos = var_name.find("/");
10169 bool uses_per_variable_naming = (slash_pos != std::string::npos);
10170
10171 if (uses_per_variable_naming && colons.size() % 2 == 1) {
10172 size_t middle_colon_pos = colons[colons.size() / 2];
10173 std::string slash_to_mid = var_name.substr(slash_pos + 1, middle_colon_pos - slash_pos - 1);
10174 std::string mid_to_end = var_name.substr(middle_colon_pos + 1);
10175
10176 if (slash_to_mid == mid_to_end) {
10177 // Special case - we have a string of the form Beamlime/GS2:FC1:GS2:FC1.
10178 // Logger has already warned people that having colons in the equipment/event
10179 // names is a bad idea, so we only need to worry about them in the tag name.
10181 } else {
10182 // We have a string of the form Beamlime/Demand:GS2:FC1. Split at the first colon.
10183 split_pos = colons[0];
10184 }
10185 } else {
10186 // Normal case - split at the fist colon.
10187 split_pos = colons[0];
10188 }
10189
10190 event_name = var_name.substr(0, split_pos);
10191 tag_name = var_name.substr(split_pos + 1);
10192 }
10193}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ starts_with()

bool starts_with ( const std::string &  s1,
const char s2 
)

Definition at line 4427 of file mhttpd.cxx.

4428{
4429 if (s1.length() < strlen(s2))
4430 return false;
4431 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4432}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode()

void strencode ( Return r,
const char text 
)

Definition at line 2019 of file mhttpd.cxx.

2020{
2021 size_t len = strlen(text);
2022 for (size_t i = 0; i < len; i++) {
2023 switch (text[i]) {
2024 case '\n':
2025 r->rsprintf("<br>\n");
2026 break;
2027 case '<':
2028 r->rsprintf("&lt;");
2029 break;
2030 case '>':
2031 r->rsprintf("&gt;");
2032 break;
2033 case '&':
2034 r->rsprintf("&amp;");
2035 break;
2036 case '\"':
2037 r->rsprintf("&quot;");
2038 break;
2039 default:
2040 r->rsprintf("%c", text[i]);
2041 }
2042 }
2043}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode2()

std::string strencode2 ( const char text)

Definition at line 2047 of file mhttpd.cxx.

2048{
2049 std::string b;
2050 size_t len = strlen(text);
2051 for (size_t i = 0; i < len; i++) {
2052 switch (text[i]) {
2053 case '\n':
2054 b += "<br>\n";
2055 break;
2056 case '<':
2057 b += "&lt;";
2058 break;
2059 case '>':
2060 b += "&gt;";
2061 break;
2062 case '&':
2063 b += "&amp;";
2064 break;
2065 case '\"':
2066 b += "&quot;";
2067 break;
2068 default:
2069 b += text[i];
2070 break;
2071 }
2072 }
2073 return b;
2074}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode3()

void strencode3 ( Return r,
const char text 
)

Definition at line 2078 of file mhttpd.cxx.

2079{
2080 size_t len = strlen(text);
2081 for (size_t i = 0; i < len; i++) {
2082 switch (text[i]) {
2083 case '<':
2084 r->rsprintf("&lt;");
2085 break;
2086 case '>':
2087 r->rsprintf("&gt;");
2088 break;
2089 case '&':
2090 r->rsprintf("&amp;");
2091 break;
2092 case '\"':
2093 r->rsprintf("&quot;");
2094 break;
2095 default:
2096 r->rsprintf("%c", text[i]);
2097 }
2098 }
2099}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ strencode4()

void strencode4 ( Return r,
const char text 
)

Definition at line 2103 of file mhttpd.cxx.

2104{
2105 size_t len = strlen(text);
2106 for (size_t i = 0; i < len; i++) {
2107 switch (text[i]) {
2108 case '\n':
2109 r->rsprintf("<br>\n");
2110 break;
2111 case '<':
2112 r->rsprintf("&lt;");
2113 break;
2114 case '>':
2115 r->rsprintf("&gt;");
2116 break;
2117 case '&':
2118 r->rsprintf("&amp;");
2119 break;
2120 case '\"':
2121 r->rsprintf("&quot;");
2122 break;
2123 case ' ':
2124 r->rsprintf("&nbsp;");
2125 break;
2126 default:
2127 r->rsprintf("%c", text[i]);
2128 }
2129 }
2130}
Here is the call graph for this function:

◆ string_to_time()

time_t string_to_time ( const char str)

Definition at line 8117 of file mhttpd.cxx.

8118{
8119 time_t t = 0;
8120 for (; *str != 0; str++) {
8121 if (*str < '0')
8122 break;
8123 if (*str > '9')
8124 break;
8125 t *= 10;
8126 t += *str - '0';
8127 }
8128 return t;
8129}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ stristr()

char * stristr ( const char str,
const char pattern 
)

Definition at line 339 of file mhttpd.cxx.

340{
341 char c1, c2, *ps, *pp;
342
343 if (str == NULL || pattern == NULL)
344 return NULL;
345
346 while (*str) {
347 ps = (char *) str;
348 pp = (char *) pattern;
349 c1 = *ps;
350 c2 = *pp;
351 if (toupper(c1) == toupper(c2)) {
352 while (*pp) {
353 c1 = *ps;
354 c2 = *pp;
355
356 if (toupper(c1) != toupper(c2))
357 break;
358
359 ps++;
360 pp++;
361 }
362
363 if (!*pp)
364 return (char *) str;
365 }
366 str++;
367 }
368
369 return NULL;
370}
Here is the call graph for this function:

◆ submit_elog()

void submit_elog ( MVOdb odb,
Param pp,
Return r,
Attachment a 
)

Definition at line 2248 of file mhttpd.cxx.

2249{
2250 char path[256], path1[256];
2251 char mail_to[256], mail_from[256], mail_list[256],
2252 smtp_host[256], tag[80], mail_param[1000];
2253 char *p, *pitem;
2254 HNDLE hDB, hkey;
2255 char att_file[3][256];
2256 int fh, size, n_mail;
2257 char mhttpd_full_url[256];
2258
2260 mstrlcpy(att_file[0], pp->getparam("attachment0"), sizeof(att_file[0]));
2261 mstrlcpy(att_file[1], pp->getparam("attachment1"), sizeof(att_file[1]));
2262 mstrlcpy(att_file[2], pp->getparam("attachment2"), sizeof(att_file[2]));
2263
2264 /* check for valid attachment files */
2265 for (int i = 0; i < 3; i++) {
2266 char str[256];
2267 sprintf(str, "attachment%d", i);
2268 //printf("submit_elog: att %d, [%s] param [%s], size %d\n", i, str, pp->getparam(str), a->_attachment_size[i]);
2269 if (pp->getparam(str) && *pp->getparam(str) && a->attachment_size[i] == 0) {
2270 /* replace '\' by '/' */
2271 mstrlcpy(path, pp->getparam(str), sizeof(path));
2272 mstrlcpy(path1, path, sizeof(path1));
2273 while (strchr(path, '\\'))
2274 *strchr(path, '\\') = '/';
2275
2276 /* check if valid ODB tree */
2277 if (db_find_key(hDB, 0, path, &hkey) == DB_SUCCESS) {
2278 std::string bout;
2279 gen_odb_attachment(r, path, bout);
2280 int bufsize = bout.length()+1;
2281 char* buf = (char*)M_MALLOC(bufsize);
2282 memcpy(buf, bout.c_str(), bufsize);
2283 mstrlcpy(att_file[i], path, sizeof(att_file[0]));
2284 mstrlcat(att_file[i], ".html", sizeof(att_file[0]));
2285 a->attachment_buffer[i] = buf;
2287 }
2288 /* check if local file */
2289 else if ((fh = open(path1, O_RDONLY | O_BINARY)) >= 0) {
2290 size = lseek(fh, 0, SEEK_END);
2291 char* buf = (char*)M_MALLOC(size);
2292 lseek(fh, 0, SEEK_SET);
2293 int rd = read(fh, buf, size);
2294 if (rd < 0)
2295 rd = 0;
2296 close(fh);
2297 mstrlcpy(att_file[i], path, sizeof(att_file[0]));
2298 a->attachment_buffer[i] = buf;
2299 a->attachment_size[i] = rd;
2300 } else if (strncmp(path, "/HS/", 4) == 0) {
2301 char* buf = (char*)M_MALLOC(100000);
2302 size = 100000;
2303 mstrlcpy(str, path + 4, sizeof(str));
2304 if (strchr(str, '?')) {
2305 p = strchr(str, '?') + 1;
2306 p = strtok(p, "&");
2307 while (p != NULL) {
2308 pitem = p;
2309 p = strchr(p, '=');
2310 if (p != NULL) {
2311 *p++ = 0;
2312 urlDecode(pitem); // parameter name
2313 urlDecode(p); // parameter value
2314
2315 pp->setparam(pitem, p);
2316
2317 p = strtok(NULL, "&");
2318 }
2319 }
2320 *strchr(str, '?') = 0;
2321 }
2322 show_hist_page(odb, pp, r, "image.gif", buf, &size, 0);
2323 mstrlcpy(att_file[i], str, sizeof(att_file[0]));
2324 a->attachment_buffer[i] = buf;
2325 a->attachment_size[i] = size;
2326 pp->unsetparam("scale");
2327 pp->unsetparam("offset");
2328 pp->unsetparam("width");
2329 pp->unsetparam("index");
2330 } else {
2331 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2332 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2333 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
2334
2335 r->rsprintf("<html><head>\n");
2336 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
2337 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
2338 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
2339 r->rsprintf("<title>ELog Error</title></head>\n");
2340 r->rsprintf("<i>Error: Attachment file <i>%s</i> not valid.</i><p>\n", pp->getparam(str));
2341 r->rsprintf("Please go back and enter a proper filename (use the <b>Browse</b> button).\n");
2342 r->rsprintf("<body></body></html>\n");
2343 return;
2344 }
2345 }
2346 }
2347
2348 int edit = atoi(pp->getparam("edit"));
2349 //printf("submit_elog: edit [%s] %d, orig [%s]\n", pp->getparam("edit"), edit, pp->getparam("orig"));
2350
2351 tag[0] = 0;
2352 if (edit) {
2353 mstrlcpy(tag, pp->getparam("orig"), sizeof(tag));
2354 }
2355
2356 int status = el_submit(atoi(pp->getparam("run")),
2357 pp->getparam("author"),
2358 pp->getparam("type"),
2359 pp->getparam("system"),
2360 pp->getparam("subject"),
2361 pp->getparam("text"),
2362 pp->getparam("orig"),
2363 *pp->getparam("html") ? "HTML" : "plain",
2364 att_file[0], a->attachment_buffer[0], a->attachment_size[0],
2365 att_file[1], a->attachment_buffer[1], a->attachment_size[1],
2366 att_file[2], a->attachment_buffer[2], a->attachment_size[2],
2367 tag, sizeof(tag));
2368
2369 //printf("el_submit status %d, tag [%s]\n", status, tag);
2370
2371 if (status != EL_SUCCESS) {
2372 cm_msg(MERROR, "submit_elog", "el_submit() returned status %d", status);
2373 }
2374
2375 /* supersede host name with "/Elog/Host name" */
2376 std::string elog_host_name;
2377 db_get_value_string(hDB, 0, "/Elog/Host name", 0, &elog_host_name, TRUE);
2378
2379 // K.O. FIXME: we cannot guess the Elog URL like this because
2380 // we do not know if access is through a proxy or redirect
2381 // we do not know if it's http: or https:, etc. Better
2382 // to read the whole "mhttpd_full_url" string from ODB.
2383 sprintf(mhttpd_full_url, "http://%s/", elog_host_name.c_str());
2384
2385 /* check for mail submissions */
2386 mail_param[0] = 0;
2387 n_mail = 0;
2388
2389 for (int index = 0; index <= 1; index++) {
2390 std::string str;
2391 str += "/Elog/Email ";
2392 if (index == 0)
2393 str += pp->getparam("type");
2394 else
2395 str += pp->getparam("system");
2396
2397 if (db_find_key(hDB, 0, str.c_str(), &hkey) == DB_SUCCESS) {
2398 size = sizeof(mail_list);
2400
2401 if (db_find_key(hDB, 0, "/Elog/SMTP host", &hkey) != DB_SUCCESS) {
2402 show_error(r, "No SMTP host defined under /Elog/SMTP host");
2403 return;
2404 }
2405 size = sizeof(smtp_host);
2407
2408 p = strtok(mail_list, ",");
2409 while (1) {
2410 mstrlcpy(mail_to, p, sizeof(mail_to));
2411
2412 std::string exptname;
2413 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
2414
2415 sprintf(mail_from, "MIDAS %s <MIDAS@%s>", exptname.c_str(), elog_host_name.c_str());
2416
2417 std::string mail_text;
2418 mail_text += "A new entry has been submitted by ";
2419 mail_text += pp->getparam("author");
2420 mail_text += "\n";
2421 mail_text += "\n";
2422
2423 mail_text += "Experiment : ";
2424 mail_text += exptname.c_str();
2425 mail_text += "\n";
2426
2427 mail_text += "Type : ";
2428 mail_text += pp->getparam("type");
2429 mail_text += "\n";
2430
2431 mail_text += "System : ";
2432 mail_text += pp->getparam("system");
2433 mail_text += "\n";
2434
2435 mail_text += "Subject : ";
2436 mail_text += pp->getparam("subject");
2437 mail_text += "\n";
2438
2439 mail_text += "Link : ";
2441 mail_text += "/EL/";
2442 mail_text += tag;
2443 mail_text += "\n";
2444
2445 mail_text += "\n";
2446
2447 mail_text += pp->getparam("text");
2448 mail_text += "\n";
2449
2450 sendmail(elog_host_name.c_str(), smtp_host, mail_from, mail_to, pp->getparam("type"), mail_text.c_str());
2451
2452 if (mail_param[0] == 0)
2453 mstrlcpy(mail_param, "?", sizeof(mail_param));
2454 else
2455 mstrlcat(mail_param, "&", sizeof(mail_param));
2456 sprintf(mail_param + strlen(mail_param), "mail%d=%s", n_mail++, mail_to);
2457
2458 p = strtok(NULL, ",");
2459 if (!p)
2460 break;
2461 while (*p == ' ')
2462 p++;
2463 }
2464 }
2465 }
2466
2467 r->rsprintf("HTTP/1.1 302 Found\r\n");
2468 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2469
2470 //if (mail_param[0])
2471 // r->rsprintf("Location: ../EL/%s?%s\n\n<html>redir</html>\r\n", tag, mail_param + 1);
2472 //else
2473 // r->rsprintf("Location: ../EL/%s\n\n<html>redir</html>\r\n", tag);
2474
2475 if (mail_param[0])
2476 r->rsprintf("Location: ?cmd=Show+elog&tag=%s&%s\n\n<html>redir</html>\r\n", tag, mail_param + 1);
2477 else
2478 r->rsprintf("Location: ?cmd=Show+elog&tag=%s\n\n<html>redir</html>\r\n", tag);
2479}
INT el_submit(int run, const char *author, const char *type, const char *syst, const char *subject, const char *text, const char *reply_to, const char *encoding, const char *afilename1, const char *buffer1, INT buffer_size1, const char *afilename2, const char *buffer2, INT buffer_size2, const char *afilename3, const char *buffer3, INT buffer_size3, char *tag, INT tag_size)
Definition elog.cxx:124
#define EL_SUCCESS
Definition midas.h:745
INT sendmail(const char *from_host, const char *smtp_host, const char *from, const char *to, const char *subject, const char *text)
Definition mhttpd.cxx:1253
void gen_odb_attachment(Return *r, const char *path, std::string &bout)
Definition mhttpd.cxx:2134
Here is the call graph for this function:
Here is the caller graph for this function:

◆ taxis()

void taxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  xr,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  xmin,
double  xmax 
)

Definition at line 7785 of file mhttpd.cxx.

7788{
7791 char str[80];
7792 const int base[] = { 1, 5, 10, 60, 300, 600, 1800, 3600, 3600 * 6, 3600 * 12, 3600 * 24, 0 };
7793 time_t ltime;
7794 int force_date, d1, d2;
7795 struct tm tms;
7796
7797 if (xmax <= xmin || width <= 0)
7798 return;
7799
7800 /* force date display if xmax not today */
7801 ltime = ss_time();
7802 localtime_r(&ltime, &tms);
7803 d1 = tms.tm_mday;
7804 ltime = (time_t) xmax;
7805 localtime_r(&ltime, &tms);
7806 d2 = tms.tm_mday;
7807 force_date = (d1 != d2);
7808
7809 /* use 5 pixel as min tick distance */
7810 dx = (int) ((xmax - xmin) / (double) (width / 5) + 0.5);
7811
7812 for (tick_base = 0; base[tick_base]; tick_base++) {
7813 if (base[tick_base] > dx)
7814 break;
7815 }
7816 if (!base[tick_base])
7817 tick_base--;
7818 dx = base[tick_base];
7819
7820 if (base[tick_base + 1])
7821 major_base = tick_base + 1;
7822 else
7825
7826 if (base[major_base + 1])
7827 label_base = major_base + 1;
7828 else
7831
7832 do {
7833 sec_to_label(str, (int) (xmin + 0.5), label_dx, force_date);
7834 maxwidth = font->h / 2 * strlen(str);
7835
7836 /* increasing label_dx, if labels would overlap */
7837 if (maxwidth > 0.7 * label_dx / (xmax - xmin) * width) {
7838 if (base[label_base + 1])
7840 else
7841 label_dx += 3600 * 24;
7842 } else
7843 break;
7844 } while (1);
7845
7846 x_act =
7847 (int) floor((double) (xmin - ss_timezone()) / label_dx) * label_dx + ss_timezone();
7848
7849 gdImageLine(im, x1, y1, x1 + width, y1, col);
7850
7851 do {
7852 x_screen = (int) ((x_act - xmin) / (xmax - xmin) * width + x1 + 0.5);
7853 xs = (int) (x_screen + 0.5);
7854
7855 if (x_screen > x1 + width + 0.001)
7856 break;
7857
7858 if (x_screen >= x1) {
7859 if ((x_act - ss_timezone()) % major_dx == 0) {
7860 if ((x_act - ss_timezone()) % label_dx == 0) {
7861 /* label tick mark */
7862 gdImageLine(im, xs, y1, xs, y1 + text, col);
7863
7864 /* grid line */
7865 if (grid != 0 && xs > x1 && xs < x1 + width)
7866 gdImageLine(im, xs, y1, xs, y1 + grid, col);
7867
7868 /* label */
7869 if (label != 0) {
7871
7872 /* if labels at edge, shift them in */
7873 xl = (int) xs - font->w * strlen(str) / 2;
7874 if (xl < 0)
7875 xl = 0;
7876 if (xl + font->w * (int) strlen(str) > xr)
7877 xl = xr - font->w * strlen(str);
7878 gdImageString(im, font, xl, y1 + label, str, col);
7879 }
7880 } else {
7881 /* major tick mark */
7882 gdImageLine(im, xs, y1, xs, y1 + major, col);
7883
7884 /* grid line */
7885 if (grid != 0 && xs > x1 && xs < x1 + width)
7886 gdImageLine(im, xs, y1 - 1, xs, y1 + grid, gcol);
7887 }
7888
7889 } else
7890 /* minor tick mark */
7891 gdImageLine(im, xs, y1, xs, y1 + minor, col);
7892
7893 }
7894
7895 x_act += dx;
7896
7897 /* supress 1.23E-17 ... */
7898 if (fabs((double)x_act) < dx / 100)
7899 x_act = 0;
7900
7901 } while (1);
7902}
INT ss_timezone()
Definition system.cxx:3580
void sec_to_label(char *result, int sec, int base, int force_date)
Definition mhttpd.cxx:7750
Here is the call graph for this function:
Here is the caller graph for this function:

◆ time_to_sec()

int time_to_sec ( const char str)

Definition at line 8092 of file mhttpd.cxx.

8093{
8094 double s;
8095
8096 s = atof(str);
8097 switch (str[strlen(str) - 1]) {
8098 case 'm':
8099 case 'M':
8100 s *= 60;
8101 break;
8102 case 'h':
8103 case 'H':
8104 s *= 3600;
8105 break;
8106 case 'd':
8107 case 'D':
8108 s *= 3600 * 24;
8109 break;
8110 }
8111
8112 return (int) s;
8113}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ time_to_string()

std::string time_to_string ( time_t  t)

Definition at line 8133 of file mhttpd.cxx.

8134{
8135 char buf[256];
8136 sprintf(buf, "%.0f", (double)t);
8137 return buf;
8138}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toString()

static std::string toString ( int  i)
static

Definition at line 55 of file mhttpd.cxx.

56{
57 char buf[256];
58 sprintf(buf, "%d", i);
59 return buf;
60}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_file_mg()

int try_file_mg ( const char try_dir,
const char filename,
std::string &  path,
FILE **  fpp,
bool  trace 
)

Definition at line 13639 of file mhttpd.cxx.

13640{
13641 if (fpp)
13642 *fpp = NULL;
13643 if (!try_dir)
13644 return SS_FILE_ERROR;
13645 if (strlen(try_dir) < 1)
13646 return SS_FILE_ERROR;
13647
13648 path = try_dir;
13649 if (path[path.length()-1] != DIR_SEPARATOR)
13650 path += DIR_SEPARATOR_STR;
13651 path += filename;
13652
13653 FILE* fp = fopen(path.c_str(), "r");
13654
13655 if (trace) {
13656 if (fp)
13657 printf("file \"%s\": OK!\n", path.c_str());
13658 else
13659 printf("file \"%s\": not found.\n", path.c_str());
13660 }
13661
13662 if (!fp)
13663 return SS_FILE_ERROR;
13664 else if (fpp)
13665 *fpp = fp;
13666 else
13667 fclose(fp);
13668
13669 return SUCCESS;
13670}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12246 of file mhttpd.cxx.

12247{
12249 gMutex.unlock();
12250}
double fTimeUnlocked
Definition mhttpd.cxx:388
Here is the call graph for this function:
Here is the caller graph for this function:

◆ urlDecode()

static void urlDecode ( char p)
static

Definition at line 880 of file mhttpd.cxx.

884{
885 //char *px = p;
886 char *pD, str[3];
887 int i;
888
889 //printf("URL decode: [%s] --> ", p);
890
891 pD = p;
892 while (*p) {
893 if (*p == '%') {
894 /* Escape: next 2 chars are hex representation of the actual character */
895 p++;
896 if (isxdigit(p[0]) && isxdigit(p[1])) {
897 str[0] = p[0];
898 str[1] = p[1];
899 str[2] = 0;
900 sscanf(str, "%02X", &i);
901
902 *pD++ = (char) i;
903 p += 2;
904 } else
905 *pD++ = '%';
906 } else if (*p == '+') {
907 /* convert '+' to ' ' */
908 *pD++ = ' ';
909 p++;
910 } else {
911 *pD++ = *p++;
912 }
913 }
914 *pD = '\0';
915
916 //printf("[%s]\n", px);
917}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UrlDecode()

static std::string UrlDecode ( const char p)
static

Definition at line 841 of file mhttpd.cxx.

845{
846 std::string s;
847
848 //printf("URL decode: [%s] --> ", p);
849
850 while (*p) {
851 if (*p == '%') {
852 /* Escape: next 2 chars are hex representation of the actual character */
853 p++;
854 if (isxdigit(p[0]) && isxdigit(p[1])) {
855 int i = 0;
856 char str[3];
857 str[0] = p[0];
858 str[1] = p[1];
859 str[2] = 0;
860 sscanf(str, "%02X", &i);
861
862 s += (char) i;
863 p += 2;
864 } else
865 s += '%';
866 } else if (*p == '+') {
867 /* convert '+' to ' ' */
868 s += ' ';
869 p++;
870 } else {
871 s += *p++;
872 }
873 }
874
875 //printf("[%s]\n", s.c_str());
876
877 return s;
878}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ urlEncode() [1/2]

static void urlEncode ( char ps,
int  ps_size 
)
static

Definition at line 919 of file mhttpd.cxx.

924{
925 char *pd, *p;
926 int len = strlen(ps);
927 char *str = (char*)malloc(len*3 + 10); // at worst, each input character is expanded into 3 output characters
928
929 pd = str;
930 p = ps;
931 while (*p) {
932 if (isalnum(*p)) {
933 *pd++ = *p++;
934 } else {
935 sprintf(pd, "%%%02X", (*p)&0xFF);
936 pd += 3;
937 p++;
938 }
939 }
940 *pd = '\0';
941
942 if (/* DISABLES CODE */ (0)) {
943 printf("urlEncode [");
944 for (p=ps; *p!=0; p++)
945 printf("0x%02x ", (*p)&0xFF);
946 printf("]\n");
947
948 printf("urlEncode [%s] -> [%s]\n", ps, str);
949 }
950
952 free(str);
953}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ urlEncode() [2/2]

static std::string urlEncode ( const char text)
static

Definition at line 955 of file mhttpd.cxx.

960{
961 std::string encoded;
962
963 const char* p = text;
964 while (*p) {
965 if (isalnum(*p)) {
966 encoded += *p++;
967 } else {
968 char buf[16];
969 sprintf(buf, "%%%02X", (*p)&0xFF);
970 encoded += buf;
971 p++;
972 }
973 }
974
975 if (/* DISABLES CODE */ (0)) {
976 printf("urlEncode [");
977 for (p=text; *p!=0; p++)
978 printf("0x%02x ", (*p)&0xFF);
979 printf("]\n");
980
981 printf("urlEncode [%s] -> [%s]\n", text, encoded.c_str());
982 }
983
984 return encoded;
985}
Here is the call graph for this function:

◆ vaxis()

int vaxis ( gdImagePtr  im,
gdFont font,
int  col,
int  gcol,
int  x1,
int  y1,
int  width,
int  minor,
int  major,
int  text,
int  label,
int  grid,
double  ymin,
double  ymax,
BOOL  logaxis 
)

Definition at line 7906 of file mhttpd.cxx.

7910{
7913 int last_label_y;
7914 char str[80];
7915 const double base[] = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000 };
7916
7917 if (ymax <= ymin || width <= 0)
7918 return 0;
7919
7920 // data type "double" only has about 15 significant digits, if difference between ymax and ymin is less than 10 significant digits, bailout! Otherwise code below goes into infinite loop
7921 if (fabs(ymax - ymin) <= 1e-10)
7922 return 0;
7923
7924 if (logaxis) {
7925 dy = pow(10, floor(log(ymin) / LN10));
7926 label_dy = dy;
7927 major_dy = dy * 10;
7928 n_sig1 = 4;
7929 } else {
7930 dy = (ymax - ymin) / (double) (width / 5);
7931
7932 frac_dy = modf(log(dy) / LN10, &int_dy);
7933 if (frac_dy < 0) {
7934 frac_dy += 1;
7935 int_dy -= 1;
7936 }
7937
7938 tick_base = frac_dy < LOG2 ? 1 : frac_dy < LOG5 ? 2 : 3;
7940
7941 /* rounding up of dy, label_dy */
7942 dy = pow(10, int_dy) * base[tick_base];
7943 major_dy = pow(10, int_dy) * base[major_base];
7945
7946 /* number of significant digits */
7947 if (ymin == 0)
7948 n_sig1 = 0;
7949 else
7950 n_sig1 =
7951 (int) floor(log(fabs(ymin)) / LN10) -
7952 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7953
7954 if (ymax == 0)
7955 n_sig2 = 0;
7956 else
7957 n_sig2 =
7958 (int) floor(log(fabs(ymax)) / LN10) -
7959 (int) floor(log(fabs(label_dy)) / LN10) + 1;
7960
7961 n_sig1 = MAX(n_sig1, n_sig2);
7962 n_sig1 = MAX(n_sig1, 4);
7963
7964 /* increasing label_dy, if labels would overlap */
7965 while (label_dy / (ymax - ymin) * width < 1.5 * font->h) {
7966 label_base++;
7967 label_dy = pow(10, int_dy) * base[label_base];
7968 if (label_base % 3 == 2 && major_base % 3 == 1) {
7969 major_base++;
7970 major_dy = pow(10, int_dy) * base[major_base];
7971 }
7972 }
7973 }
7974
7975 max_width = 0;
7976 y_act = floor(ymin / dy) * dy;
7977
7978 if (x1 != 0 || y1 != 0)
7979 gdImageLine(im, x1, y1, x1, y1 - width, col);
7980
7981 last_label_y = y1 + 2 * font->h;
7982
7983 do {
7984 if (logaxis)
7985 y_screen = y1 - (log(y_act) - log(ymin)) / (log(ymax) - log(ymin)) * width;
7986 else
7987 y_screen = y1 - (y_act - ymin) / (ymax - ymin) * width;
7988 ys = (int) (y_screen + 0.5);
7989
7990 if (y_screen < y1 - width - 0.001)
7991 break;
7992
7993 if (y_screen <= y1 + 0.001) {
7994 if (fabs(floor(y_act / major_dy + 0.5) - y_act / major_dy) <
7995 dy / major_dy / 10.0) {
7996 if (fabs(floor(y_act / label_dy + 0.5) - y_act / label_dy) <
7997 dy / label_dy / 10.0) {
7998 if (x1 != 0 || y1 != 0) {
7999 /* label tick mark */
8000 gdImageLine(im, x1, ys, x1 + text, ys, col);
8001
8002 /* grid line */
8003 if (grid != 0 && y_screen < y1 && y_screen > y1 - width) {
8004 if (grid > 0)
8005 gdImageLine(im, x1 + 1, ys, x1 + grid, ys, gcol);
8006 else
8007 gdImageLine(im, x1 - 1, ys, x1 + grid, ys, gcol);
8008 }
8009
8010 /* label */
8011 if (label != 0) {
8012 sprintf(str, "%1.*lG", n_sig1, y_act);
8013 if (label < 0)
8014 gdImageString(im, font, x1 + label - font->w * strlen(str),
8015 ys - font->h / 2, str, col);
8016 else
8017 gdImageString(im, font, x1 + label, ys - font->h / 2, str, col);
8018
8019 last_label_y = ys - font->h / 2;
8020 }
8021 } else {
8022 sprintf(str, "%1.*lG", n_sig1, y_act);
8023 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8024 }
8025 } else {
8026 if (x1 != 0 || y1 != 0) {
8027 /* major tick mark */
8028 gdImageLine(im, x1, ys, x1 + major, ys, col);
8029
8030 /* grid line */
8031 if (grid != 0 && y_screen < y1 && y_screen > y1 - width)
8032 gdImageLine(im, x1, ys, x1 + grid, ys, col);
8033 }
8034 }
8035 if (logaxis) {
8036 dy *= 10;
8037 major_dy *= 10;
8038 label_dy *= 10;
8039 }
8040
8041 } else {
8042 if (x1 != 0 || y1 != 0) {
8043 /* minor tick mark */
8044 gdImageLine(im, x1, ys, x1 + minor, ys, col);
8045 }
8046
8047 /* for logaxis, also put labes on minor tick marks */
8048 if (logaxis) {
8049 if (label != 0) {
8050 if (x1 != 0 || y1 != 0) {
8051 /* calculate position of next major label */
8052 y_next = pow(10, floor(log(y_act) / LN10) + 1);
8053 y_screen =
8054 (int) (y1 -
8055 (log(y_next) - log(ymin)) / (log(ymax) -
8056 log(ymin)) * width + 0.5);
8057
8058 if (ys + font->h / 2 < last_label_y
8059 && ys - font->h / 2 > y_screen + font->h / 2) {
8060 sprintf(str, "%1.*lG", n_sig1, y_act);
8061 if (label < 0)
8062 gdImageString(im, font, x1 + label - font->w * strlen(str),
8063 ys - font->h / 2, str, col);
8064 else
8065 gdImageString(im, font, x1 + label, ys - font->h / 2, str,
8066 col);
8067 }
8068
8069 last_label_y = ys - font->h / 2;
8070 } else {
8071 sprintf(str, "%1.*lG", n_sig1, y_act);
8072 max_width = MAX(max_width, (int) (font->w * strlen(str)));
8073 }
8074 }
8075 }
8076 }
8077 }
8078
8079 y_act += dy;
8080
8081 /* supress 1.23E-17 ... */
8082 if (fabs(y_act) < dy / 100)
8083 y_act = 0;
8084
8085 } while (1);
8086
8087 return max_width + abs(label);
8088}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xdb_find_key()

static int xdb_find_key ( HNDLE  hDB,
HNDLE  dir,
const char str,
HNDLE hKey,
int  tid,
int  size 
)
static

Definition at line 10078 of file mhttpd.cxx.

10079{
10080 int status = db_find_key(hDB, dir, str, hKey);
10081 if (status == DB_SUCCESS)
10082 return status;
10083
10084 db_create_key(hDB, dir, str, tid);
10085 status = db_find_key(hDB, dir, str, hKey);
10086 if (status != DB_SUCCESS || !*hKey) {
10087 cm_msg(MERROR, "xdb_find_key", "Invalid ODB path \"%s\"", str);
10088 str = "bad_xdb_find_key";
10089 db_create_key(hDB, dir, str, tid);
10090 db_find_key(hDB, dir, str, hKey);
10091 }
10092 assert(*hKey);
10093
10094 if (tid == TID_STRING) {
10095 db_set_data_index(hDB, *hKey, "", size, 0, TID_STRING);
10096 }
10097
10098 return status;
10099}
Here is the call graph for this function:

◆ xdb_get_data_index()

int xdb_get_data_index ( HNDLE  hDB,
const char str,
void value,
int  size,
int  index,
int  tid 
)

Definition at line 10062 of file mhttpd.cxx.

10063{
10064 HNDLE hKey;
10065 int status = db_find_key(hDB, 0, str, &hKey);
10066 if (status != DB_SUCCESS)
10067 return status;
10068
10069 KEY key;
10070 db_get_key(hDB, hKey, &key);
10071 if (index >= key.num_values)
10072 return DB_OUT_OF_RANGE;
10073
10074 status = db_get_data_index(hDB, hKey, value, &size, index, tid);
10075 return status;
10076}
#define DB_OUT_OF_RANGE
Definition midas.h:651
Here is the call graph for this function:

◆ xmg_check_nonce()

static int xmg_check_nonce ( const char nonce)
static

Definition at line 13775 of file mhttpd.cxx.

13775 {
13776 unsigned long now = (unsigned long) time(NULL);
13777 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13778 return now < val || now - val < 3600;
13779}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xmg_http_send_digest_auth_request()

static void xmg_http_send_digest_auth_request ( struct mg_connection c,
const char domain 
)
static

Definition at line 13786 of file mhttpd.cxx.

13787 {
13788 mg_printf(c,
13789 "HTTP/1.1 401 Unauthorized\r\n"
13790 "WWW-Authenticate: Digest qop=\"auth\", "
13791 "realm=\"%s\", nonce=\"%lu\"\r\n"
13792 "Content-Length: 0\r\n\r\n",
13793 domain, (unsigned long) time(NULL));
13794}
int mg_printf(struct mg_connection *, PRINTF_FORMAT_STRING(const char *fmt),...) PRINTF_ARGS(2
Here is the call graph for this function:
Here is the caller graph for this function:

◆ xmg_mkmd5resp()

static void xmg_mkmd5resp ( const char method,
size_t  method_len,
const char uri,
size_t  uri_len,
const char ha1,
size_t  ha1_len,
const char nonce,
size_t  nonce_len,
const char nc,
size_t  nc_len,
const char cnonce,
size_t  cnonce_len,
const char qop,
size_t  qop_len,
char resp 
)
static

Definition at line 13754 of file mhttpd.cxx.

13758 {
13759 static const char colon[] = ":";
13760 static const size_t one = 1;
13761 char ha2[33];
13762
13763 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13764 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13765 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13766 colon, one, ha2, sizeof(ha2) - 1, NULL);
13767}
char * cs_md5(char buf[33],...)
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _abort

Definition at line 13451 of file mhttpd.cxx.

13451{false};

◆ cgif_bar_str

const char* cgif_bar_str[]
static
Initial value:
= {
"Src = STRING : [256] ",
"X = INT : 0",
"Y = INT : 0",
"Width = INT : 10",
"Height = INT : 100",
"Direction = INT : 0",
"Axis = INT : 1",
"Logscale = BOOL : n",
"Min = DOUBLE : 0",
"Max = DOUBLE : 10",
"FGColor = STRING : [8] 000000",
"BGColor = STRING : [8] FFFFFF",
"BDColor = STRING : [8] 808080",
}

Definition at line 3468 of file mhttpd.cxx.

3468 {
3469 "Src = STRING : [256] ",
3470 "X = INT : 0",
3471 "Y = INT : 0",
3472 "Width = INT : 10",
3473 "Height = INT : 100",
3474 "Direction = INT : 0",
3475 "Axis = INT : 1",
3476 "Logscale = BOOL : n",
3477 "Min = DOUBLE : 0",
3478 "Max = DOUBLE : 10",
3479 "FGColor = STRING : [8] 000000",
3480 "BGColor = STRING : [8] FFFFFF",
3481 "BDColor = STRING : [8] 808080",
3482 NULL
3483};

◆ cgif_label_str

const char* cgif_label_str[]
static
Initial value:
= {
"Src = STRING : [256] ",
"Format = STRING : [32] %1.1f",
"Font = STRING : [32] Medium",
"X = INT : 0",
"Y = INT : 0",
"Align = INT : 0",
"FGColor = STRING : [8] 000000",
"BGColor = STRING : [8] FFFFFF",
}

Definition at line 3428 of file mhttpd.cxx.

3428 {
3429 "Src = STRING : [256] ",
3430 "Format = STRING : [32] %1.1f",
3431 "Font = STRING : [32] Medium",
3432 "X = INT : 0",
3433 "Y = INT : 0",
3434 "Align = INT : 0",
3435 "FGColor = STRING : [8] 000000",
3436 "BGColor = STRING : [8] FFFFFF",
3437 NULL
3438};

◆ default_system_list

const char default_system_list[20][NAME_LENGTH]
static
Initial value:
= {
"General",
"DAQ",
"Detector",
"Electronics",
"Target",
"Beamline"
}

Definition at line 114 of file mhttpd.cxx.

114 {
115 "General",
116 "DAQ",
117 "Detector",
118 "Electronics",
119 "Target",
120 "Beamline"
121};

◆ default_type_list

const char default_type_list[20][NAME_LENGTH]
static
Initial value:
= {
"Routine",
"Shift summary",
"Minor error",
"Severe error",
"Fix",
"Question",
"Info",
"Modification",
"Reply",
"Alarm",
"Test",
"Other"
}

Definition at line 99 of file mhttpd.cxx.

99 {
100 "Routine",
101 "Shift summary",
102 "Minor error",
103 "Severe error",
104 "Fix",
105 "Question",
106 "Info",
107 "Modification",
108 "Reply",
109 "Alarm",
110 "Test",
111 "Other"
112};

◆ elog_mode

BOOL elog_mode = FALSE
static

Definition at line 92 of file mhttpd.cxx.

◆ favicon_ico

const unsigned char favicon_ico[]

Definition at line 280 of file mhttpd.cxx.

280 {
281 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10,
282 0x10, 0x00, 0x01, 0x00, 0x04, 0x00, 0x28, 0x01,
283 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x28, 0x00,
284 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00,
285 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x0F,
289 0x0A, 0x00, 0x5C, 0x86, 0x4C, 0x00, 0x2F, 0x5E,
290 0x1A, 0x00, 0xBF, 0xD3, 0xD7, 0x00, 0x29, 0x17,
291 0x8D, 0x00, 0x50, 0xA7, 0xA4, 0x00, 0x59, 0x57,
292 0x7F, 0x00, 0xC6, 0xA3, 0xAC, 0x00, 0xFC, 0xFE,
293 0xFC, 0x00, 0x28, 0x12, 0x53, 0x00, 0x58, 0x7D,
294 0x72, 0x00, 0xC4, 0x3A, 0x34, 0x00, 0x3C, 0x3D,
295 0x69, 0x00, 0xC5, 0xB6, 0xB9, 0x00, 0x94, 0x92,
296 0x87, 0x00, 0x7E, 0x7A, 0xAA, 0x00, 0x88, 0x88,
297 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x81, 0x22,
298 0xD8, 0x88, 0x88, 0x88, 0xF6, 0xD8, 0x82, 0x22,
299 0xE8, 0x88, 0x88, 0x8D, 0x44, 0x98, 0x82, 0x22,
300 0xA8, 0x88, 0x88, 0x8F, 0x44, 0x48, 0x82, 0x22,
301 0x25, 0x76, 0x67, 0x55, 0x44, 0xF8, 0x88, 0x88,
302 0x3A, 0xC9, 0x9C, 0x53, 0x83, 0x88, 0x88, 0x88,
303 0x8D, 0x99, 0x99, 0x38, 0x88, 0x88, 0x88, 0x88,
304 0x88, 0x99, 0x9C, 0x88, 0x88, 0x88, 0x88, 0x88,
305 0x88, 0xF9, 0x9D, 0x88, 0x88, 0x88, 0x88, 0x88,
306 0x88, 0x8A, 0x58, 0x88, 0x88, 0x88, 0x88, 0x88,
307 0x88, 0x85, 0xD8, 0x88, 0x88, 0x88, 0x88, 0x88,
308 0x88, 0xEA, 0xAE, 0x88, 0x88, 0x88, 0x88, 0x88,
309 0x88, 0x00, 0x0B, 0x88, 0x88, 0x88, 0x88, 0x88,
310 0x88, 0x70, 0x0D, 0x88, 0x88, 0x88, 0x88, 0x88,
311 0x88, 0x87, 0xD8, 0x88, 0x88, 0x88, 0x88, 0x88,
312 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
321};

◆ favicon_png

const unsigned char favicon_png[]

Definition at line 215 of file mhttpd.cxx.

215 {
216 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
217 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
218 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
219 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68,
220 0x36, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D,
221 0x45, 0x07, 0xD4, 0x0B, 0x1A, 0x08, 0x37, 0x07,
222 0x0D, 0x7F, 0x16, 0x5C, 0x00, 0x00, 0x00, 0x09,
223 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2E, 0x23,
224 0x00, 0x00, 0x2E, 0x23, 0x01, 0x78, 0xA5, 0x3F,
225 0x76, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D,
226 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61,
227 0x05, 0x00, 0x00, 0x01, 0x7D, 0x49, 0x44, 0x41,
228 0x54, 0x78, 0xDA, 0x63, 0xFC, 0xFF, 0xFF, 0x3F,
229 0x03, 0x29, 0x80, 0x09, 0xAB, 0xE8, 0xD2, 0x65,
230 0x77, 0x36, 0x6F, 0x7E, 0x8A, 0x5D, 0xC7, 0x7F,
231 0x0C, 0x30, 0x67, 0xEE, 0x0D, 0x56, 0xCE, 0xCD,
232 0x5C, 0xBC, 0x3B, 0xB6, 0x6D, 0x7F, 0x81, 0x29,
233 0xCB, 0x88, 0xE6, 0x24, 0x20, 0x57, 0x50, 0x7C,
234 0xDD, 0xCF, 0x1F, 0x6C, 0x40, 0xCB, 0xB5, 0xB5,
235 0x05, 0xCF, 0x1C, 0xB7, 0x42, 0xB3, 0x80, 0x05,
236 0x8D, 0xCF, 0xC8, 0xC8, 0x58, 0x5A, 0x2A, 0xFB,
237 0xF6, 0x4D, 0x37, 0x1B, 0xAB, 0xA0, 0xB4, 0x4C,
238 0x0A, 0x51, 0x4E, 0x02, 0x82, 0x85, 0xCB, 0x12,
239 0x0E, 0x1D, 0xAB, 0xC7, 0x2A, 0xC5, 0x82, 0x69,
240 0xC4, 0xAF, 0x5F, 0x7F, 0x1E, 0x3F, 0xF8, 0xCD,
241 0xCB, 0xF1, 0xF5, 0xEF, 0xDF, 0x7F, 0xCC, 0xCC,
242 0x4C, 0x84, 0x6D, 0x98, 0x59, 0xD5, 0xEB, 0xCF,
243 0xA5, 0x16, 0xC4, 0xAB, 0x71, 0x72, 0xCB, 0x21,
244 0x4C, 0x59, 0x74, 0x03, 0x5E, 0x3F, 0x7F, 0xB3,
245 0x6B, 0xD6, 0x22, 0x46, 0xA6, 0x7F, 0x0C, 0x0C,
246 0x7F, 0xD7, 0x75, 0x4D, 0xFB, 0xF1, 0xFD, 0x27,
247 0x81, 0x78, 0xB8, 0x7D, 0xE9, 0x0A, 0xCB, 0xFF,
248 0xDF, 0x4C, 0x8C, 0x8C, 0x40, 0xF6, 0xAD, 0x4B,
249 0x67, 0x1F, 0xDE, 0xBD, 0x8B, 0x45, 0x03, 0x3C,
250 0x60, 0x8F, 0x9D, 0xD8, 0xB3, 0xEB, 0x74, 0xB5,
251 0x90, 0x26, 0x07, 0x03, 0x48, 0xE4, 0x3F, 0x8F,
252 0xF6, 0xFF, 0x1B, 0x0F, 0x9A, 0x1E, 0x3E, 0x3A,
253 0xFB, 0xF3, 0xDB, 0x8F, 0xB7, 0x0F, 0x9E, 0x43,
254 0x83, 0xF1, 0xCF, 0xDF, 0x3F, 0x8A, 0x29, 0xCE,
255 0x3F, 0x7F, 0xFD, 0xFC, 0xCF, 0xF0, 0xDF, 0x98,
256 0xE9, 0xB5, 0x8F, 0xBD, 0x8A, 0x3C, 0x6F, 0xEC,
257 0xB9, 0x2D, 0x47, 0xFE, 0xFC, 0xFF, 0x6F, 0x16,
258 0x6C, 0xF3, 0xEC, 0xD3, 0x1C, 0x2E, 0x96, 0xEF,
259 0xBF, 0xAB, 0x7E, 0x32, 0x7D, 0xE2, 0x10, 0xCE,
260 0x88, 0xF4, 0x69, 0x2B, 0x60, 0xFC, 0xF4, 0xF5,
261 0x97, 0x78, 0x8A, 0x36, 0xD8, 0x44, 0x86, 0x18,
262 0x0D, 0xD7, 0x29, 0x95, 0x13, 0xD8, 0xD9, 0x58,
263 0xE1, 0x0E, 0xF8, 0xF1, 0xF3, 0xDB, 0xC6, 0xD6,
264 0xEC, 0x5F, 0x53, 0x8E, 0xBF, 0xFE, 0xC3, 0x70,
265 0x93, 0x8D, 0x6D, 0xDA, 0xCB, 0x0B, 0x4C, 0x3F,
266 0xFF, 0xFC, 0xFA, 0xCF, 0x0C, 0xB4, 0x09, 0x84,
267 0x54, 0xD5, 0x74, 0x91, 0x55, 0x03, 0x01, 0x07,
268 0x3B, 0x97, 0x96, 0x6E, 0xC8, 0x17, 0xFE, 0x7F,
269 0x4F, 0xF8, 0xFE, 0xBC, 0x95, 0x16, 0x60, 0x62,
270 0x62, 0x64, 0xE1, 0xE6, 0x60, 0x73, 0xD1, 0xB2,
271 0x7A, 0xFA, 0xE2, 0xF1, 0xDF, 0x3F, 0xFF, 0xC4,
272 0x78, 0x44, 0x31, 0xA3, 0x45, 0x2B, 0xD0, 0xE3,
273 0xF6, 0xD9, 0xE3, 0x2F, 0x2E, 0x9D, 0x29, 0xA9,
274 0xAC, 0x07, 0xA6, 0x03, 0xF4, 0xB4, 0x44, 0x10,
275 0x00, 0x00, 0x75, 0x65, 0x12, 0xB0, 0x49, 0xFF,
276 0x3F, 0x68, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
277 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
278};

◆ gAllowedHosts

std::vector<std::string> gAllowedHosts
static

Definition at line 13463 of file mhttpd.cxx.

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13752 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8143 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8142 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8152 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

Definition at line 8153 of file mhttpd.cxx.

◆ gMimeTypesOdb

MVOdb* gMimeTypesOdb = NULL
static

Definition at line 177 of file mhttpd.cxx.

◆ gMimetypeTable

const MimetypeTableEntry gMimetypeTable[]

Definition at line 128 of file mhttpd.cxx.

128 {
129 { ".ASC", "text/plain" },
130 { ".CSS", "text/css" },
131 { ".CSV", "text/csv" },
132 { ".HTM", "text/html" },
133 { ".HTML", "text/html" },
134 { ".TXT", "text/plain" },
135
136 { ".BMP", "image/bmp" },
137 { ".GIF", "image/gif" },
138 { ".ICO", "image/x-icon" },
139 { ".JPEG", "image/jpeg" },
140 { ".JPG", "image/jpeg" },
141 { ".PNG", "image/png" },
142 { ".SVG", "image/svg+xml" },
143 { ".TIF", "image/tiff" },
144 { ".TIFF", "image/tiff" },
145
146 { ".MID", "audio/midi" },
147 { ".MP3", "audio/mpeg" },
148 { ".OGA", "audio/ogg" },
149 { ".OGG", "audio/ogg" },
150 { ".WAV", "audio/wav" },
151
152 { ".BIN", "application/octet-stream" },
153 { ".BZ", "application/x-bzip" },
154 { ".BZ2", "application/x-bzip2" },
155 { ".DOC", "application/msword" },
156 { ".EPS", "application/postscript" },
157 { ".GZ", "application/gzip" },
158 { ".JS", "application/javascript" },
159 { ".JSON", "application/json" },
160 { ".MJS", "application/javascript" },
161 { ".PDF", "application/pdf" },
162 { ".PHP", "application/x-httpd-php" },
163 { ".RTF", "application/rtf" },
164 { ".PS", "application/postscript" },
165 { ".ROOT", "application/octet-stream" },
166 { ".XLS", "application/x-msexcel" },
167 { ".XML", "application/xml" },
168 { ".ZIP", "application/zip" },
169
170 { ".ODP", "application/vnd.oasis.opendocument.presentation" },
171 { ".ODS", "application/vnd.oasis.opendocument.spreadsheet" },
172 { ".ODT", "application/vnd.oasis.opendocument.text" },
173
174 { "", "" }
175};

◆ gMutex

std::mutex gMutex
static

Definition at line 45 of file mhttpd.cxx.

◆ gOdb

MVOdb* gOdb = NULL
static

Definition at line 46 of file mhttpd.cxx.

◆ gTraceBuf

RequestTraceBuf* gTraceBuf = NULL
static

Definition at line 504 of file mhttpd.cxx.

◆ history_mode

BOOL history_mode = FALSE
static

Definition at line 93 of file mhttpd.cxx.

◆ http_trace

int http_trace = 0
static

Definition at line 433 of file mhttpd.cxx.

◆ mname

const char* mname[]
extern

Definition at line 144 of file midas.cxx.

144 {
145 "January",
146 "February",
147 "March",
148 "April",
149 "May",
150 "June",
151 "July",
152 "August",
153 "September",
154 "October",
155 "November",
156 "December"
157};

◆ trace_mg

bool trace_mg = false
static

Definition at line 13705 of file mhttpd.cxx.

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13706 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13707 of file mhttpd.cxx.

◆ verbose

BOOL verbose = FALSE
static

Definition at line 94 of file mhttpd.cxx.

◆ verbose_mg

bool verbose_mg = false
static

Definition at line 13704 of file mhttpd.cxx.