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 bool trace_mg_verbose = 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 14256 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14255 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14254 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 3571 of file mhttpd.cxx.

3572{
3573 // do not append custom path to absolute filenames
3574
3575 if (filename[0] == '/')
3576 return filename;
3577 if (filename[0] == DIR_SEPARATOR)
3578 return filename;
3579
3580 HNDLE hDB;
3582
3583 std::string custom_path = "";
3584
3585 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3586
3587 if (status != DB_SUCCESS)
3588 return filename;
3589
3590 if (custom_path.length() < 1)
3591 return filename;
3592
3594 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3595 return filename;
3596 }
3597
3599
3600 std::string full_filename = custom_path;
3601 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3603 full_filename += filename;
3604
3605 return full_filename;
3606}
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:13935
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 16211 of file mhttpd.cxx.

16212{
16213 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16214 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16215}
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:16184
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16197
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 13893 of file mhttpd.cxx.

13894{
13895 char expected_response[33];
13896
13897 //printf("HereA!\n");
13898
13899 /* Parse "Authorization:" header, fail fast on parse error */
13900 struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
13901
13902 if (!hdr)
13903 return "";
13904
13905 //printf("HereB!\n");
13906
13907 std::string user = find_var_mg(hdr, "username");
13908 std::string cnonce = find_var_mg(hdr, "cnonce");
13909 std::string response = find_var_mg(hdr, "response");
13910 std::string uri = find_var_mg(hdr, "uri");
13911 std::string qop = find_var_mg(hdr, "qop");
13912 std::string nc = find_var_mg(hdr, "nc");
13913 std::string nonce = find_var_mg(hdr, "nonce");
13914
13915 if (user.length()<1) return "";
13916 if (cnonce.length()<1) return "";
13917 if (response.length()<1) return "";
13918 if (uri.length()<1) return "";
13919 if (qop.length()<1) return "";
13920 if (nc.length()<1) return "";
13921 if (nonce.length()<1) return "";
13922
13923 if (xmg_check_nonce(nonce.c_str()) == 0) return "";
13924 //printf("HereB8!\n");
13925
13926 //printf("HereC!\n");
13927
13928 const char* uri_end = strchr(hm->uri.p, ' ');
13929 if (!uri_end) return "";
13930
13931 size_t uri_length = uri_end - hm->uri.p;
13932
13933 if (uri_length != uri.length())
13934 return "";
13935
13936 int cmp = strncmp(hm->uri.p, uri.c_str(), uri_length);
13937
13938 //printf("check URI: message %d %d [%d] authorization [%s]\n", (int)hm->uri.len, uri_length, cmp, uri);
13939
13940 if (cmp != 0)
13941 return "";
13942
13943 for (unsigned i=0; i<auth->passwords.size(); i++) {
13944 AuthEntry* e = &auth->passwords[i];
13945 if (e->username != user)
13946 continue;
13947 if (e->realm != auth->realm)
13948 continue;
13949 const char* f_ha1 = e->password.c_str();
13950 int uri_len = hm->uri.len;
13951 if (hm->uri.p[uri_len] == '?')
13952 uri_len += hm->query_string.len + 1; // "+1" accounts for the "?" character
13953 xmg_mkmd5resp(hm->method.p, hm->method.len,
13954 hm->uri.p, uri_len,
13955 f_ha1, strlen(f_ha1),
13956 nonce.c_str(), nonce.length(),
13957 nc.c_str(), nc.length(),
13958 cnonce.c_str(), cnonce.length(),
13959 qop.c_str(), qop.length(),
13961 int cmp = strcasecmp(response.c_str(), expected_response);
13962 //printf("digest_auth: expected %s, got %s, cmp %d\n", expected_response, response.c_str(), cmp);
13963 if (cmp == 0) {
13964 return e->username;
13965 }
13966 }
13967
13968 return "";
13969}
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:13755
static int xmg_check_nonce(const char *nonce)
Definition mhttpd.cxx:13776
Definition mhttpd.cxx:13717
std::string password
Definition mhttpd.cxx:13720
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:12973
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:12801
KEY key
Definition mdump.cxx:34
#define EQUIPMENT_COMMON_STR
Definition midas.h:1111
#define RUNINFO_STR(_name)
Definition midas.h:1408
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:1233
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 14207 of file mhttpd.cxx.

14208{
14209 // extract password cookies
14210
14211 char cookie_pwd[256]; // general access password
14212 char cookie_wpwd[256]; // "write mode" password
14213 char cookie_cpwd[256]; // custom page and javascript password
14214
14215 cookie_pwd[0] = 0;
14216 cookie_wpwd[0] = 0;
14217 cookie_cpwd[0] = 0;
14218
14219 std::string s = find_cookie_mg(msg, "midas_pwd");
14220 if (s.length() > 0) {
14221 mstrlcpy(cookie_pwd, s.c_str(), sizeof(cookie_pwd));
14222 cookie_pwd[strcspn(cookie_pwd, " ;\r\n")] = 0;
14223 }
14224
14225 s = find_cookie_mg(msg, "midas_wpwd");
14226 if (s.length()) {
14227 mstrlcpy(cookie_wpwd, s.c_str(), sizeof(cookie_pwd));
14228 cookie_wpwd[strcspn(cookie_wpwd, " ;\r\n")] = 0;
14229 }
14230
14231 s = find_cookie_mg(msg, "cpwd");
14232 if (s.length()) {
14233 mstrlcpy(cookie_cpwd, s.c_str(), sizeof(cookie_pwd));
14234 cookie_cpwd[strcspn(cookie_cpwd, " ;\r\n")] = 0;
14235 }
14236
14237 // extract refresh rate
14238 c->refresh = DEFAULT_REFRESH;
14239 s = find_cookie_mg(msg, "midas_refr");
14240 if (s.length() > 0)
14241 c->refresh = atoi(s.c_str());
14242
14243 // extract equipment expand flag
14244 //c->expand_equipment = 0;
14245 //s = find_cookie_mg(msg, "midas_expeq");
14246 //if (s.length() > 0)
14247 // c->expand_equipment = atoi(s.c_str());
14248
14249 c->cookie_pwd = cookie_pwd;
14250 c->cookie_wpwd = cookie_wpwd;
14251 c->cookie_cpwd = cookie_cpwd;
14252}
#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:14155
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 4319 of file mhttpd.cxx.

4320{
4321 int status;
4322
4323 const char *name = p->getparam("name");
4324 const char *cmd = p->getparam("rcmd");
4325 const char *args = p->getparam("rarg");
4326
4327 if (!name || !cmd || !args) {
4329 r->rsprintf("<INVALID_ARGUMENTS>");
4330 return;
4331 }
4332
4334
4335 int buf_length = 1024;
4336
4337 int max_reply_length = atoi(p->getparam("max_reply_length"));
4340
4341 char* buf = (char*)malloc(buf_length);
4342 buf[0] = 0;
4343
4344 HNDLE hconn;
4345
4347
4348 if (status != RPC_SUCCESS) {
4349 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4350 return;
4351 }
4352
4354
4355 if (status != RPC_SUCCESS) {
4356 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4357 return;
4358 }
4359
4360 r->rsprintf("%s", buf);
4361
4362 //status = cm_disconnect_client(hconn, FALSE);
4363
4364 free(buf);
4365}
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:13480
#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 4015 of file mhttpd.cxx.

4016{
4017 static RPC_LIST rpc_list[] = {
4018 { 9999, "mhttpd_jrpc_rev0", {
4019 {TID_STRING, RPC_IN}, // arg0
4020 {TID_STRING, RPC_IN}, // arg1
4021 {TID_STRING, RPC_IN}, // arg2
4022 {TID_STRING, RPC_IN}, // arg3
4023 {TID_STRING, RPC_IN}, // arg4
4024 {TID_STRING, RPC_IN}, // arg5
4025 {TID_STRING, RPC_IN}, // arg6
4026 {TID_STRING, RPC_IN}, // arg7
4027 {TID_STRING, RPC_IN}, // arg8
4028 {TID_STRING, RPC_IN}, // arg9
4029 {0}} },
4030 { 0 }
4031 };
4032
4033 int count = 0, substring = 0, rpc;
4034
4035 const char *xname = p->getparam("name");
4036 const char *srpc = p->getparam("rpc");
4037
4038 if (!srpc || !xname) {
4040 r->rsprintf("<INVALID_ARGUMENTS>");
4041 return;
4042 }
4043
4044 char sname[256];
4045 mstrlcpy(sname, xname, sizeof(sname));
4046
4047 if (sname[strlen(sname)-1]=='*') {
4048 sname[strlen(sname)-1] = 0;
4049 substring = 1;
4050 }
4051
4052 rpc = atoi(srpc);
4053
4056 r->rsprintf("<INVALID_RPC_ID>");
4057 return;
4058 }
4059
4060 rpc_list[0].id = rpc;
4062
4064 r->rsprintf("calling rpc %d | ", rpc);
4065
4066 if (1) {
4067 int status, i;
4068 char str[256];
4070
4072
4073 /* find client which exports FCNA function */
4074 status = db_find_key(hDB, 0, "System/Clients", &hrootkey);
4075 if (status == DB_SUCCESS) {
4076 for (i=0; ; i++) {
4079 break;
4080
4081 sprintf(str, "RPC/%d", rpc);
4083 if (status == DB_SUCCESS) {
4084 char client_name[NAME_LENGTH];
4085 HNDLE hconn;
4086 int size;
4087
4088 size = sizeof(client_name);
4089 status = db_get_value(hDB, hsubkey, "Name", client_name, &size, TID_STRING, FALSE);
4090 if (status != DB_SUCCESS)
4091 continue;
4092
4093 if (strlen(sname) > 0) {
4094 if (substring) {
4095 if (strstr(client_name, sname) != client_name)
4096 continue;
4097 } else {
4098 if (strcmp(sname, client_name) != 0)
4099 continue;
4100 }
4101 }
4102
4103 count++;
4104
4105 r->rsprintf("client %s", client_name);
4106
4107 status = cm_connect_client(client_name, &hconn);
4108 r->rsprintf(" %d", status);
4109
4110 if (status == RPC_SUCCESS) {
4112 p->getparam("arg0"),
4113 p->getparam("arg1"),
4114 p->getparam("arg2"),
4115 p->getparam("arg3"),
4116 p->getparam("arg4"),
4117 p->getparam("arg5"),
4118 p->getparam("arg6"),
4119 p->getparam("arg7"),
4120 p->getparam("arg8"),
4121 p->getparam("arg9")
4122 );
4123 r->rsprintf(" %d", status);
4124
4125 //status = cm_disconnect_client(hconn, FALSE);
4126 r->rsprintf(" %d", status);
4127 }
4128
4129 r->rsprintf(" | ");
4130 }
4131 }
4132 }
4133 }
4134
4135 r->rsprintf("rpc %d, called %d clients\n", rpc, count);
4136}
#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:11835
static std::vector< RPC_LIST > rpc_list
Definition midas.cxx:11581
double count
Definition mdump.cxx:33
#define RPC_IN
Definition midas.h:1578
#define RPC_MAX_ID
Definition midas.h:1605
#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 4140 of file mhttpd.cxx.

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

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

14156{
14157 const std::string cookies = find_header_mg(msg, "Cookie");
14158 if (cookies.length() < 1)
14159 return "";
14160 const char* p = strstr(cookies.c_str(), cookie_name);
14161 if (!p)
14162 return "";
14163 const char* v = p+strlen(cookie_name);
14164 if (*v != '=')
14165 return "";
14166 v++;
14167 //printf("cookie [%s] value [%s]\n", cookie_name, v);
14168 return v;
14169}
static const std::string find_header_mg(const struct http_message *msg, const char *name)
Definition mhttpd.cxx:14142
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 14142 of file mhttpd.cxx.

14143{
14144 size_t nlen = strlen(name);
14145 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14146 if (msg->header_names[i].len != nlen)
14147 continue;
14148 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14149 continue;
14150 return mgstr(&msg->header_values[i]);
14151 }
14152 return "";
14153}
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:14137
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 3092 of file mhttpd.cxx.

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

2136{
2138 KEY key;
2139 INT i, j, size;
2140 char data[1024];
2141 time_t now;
2142
2144 db_find_key(hDB, 0, path, &hkeyroot);
2145 assert(hkeyroot);
2146
2147 /* title row */
2148 //size = sizeof(str);
2149 //str[0] = 0;
2150 //db_get_value(hDB, 0, "/Experiment/Name", str, &size, TID_STRING, TRUE);
2151 time(&now);
2152
2153 bout += "<table border=3 cellpadding=1 class=\"dialogTable\">\n";
2154 char ctimebuf[32];
2155 ctime_r(&now, ctimebuf);
2156 bout += msprintf("<tr><th colspan=2>%s</tr>\n", ctimebuf);
2157 bout += msprintf("<tr><th colspan=2>%s</tr>\n", path);
2158
2159 /* enumerate subkeys */
2160 for (i = 0;; i++) {
2162 if (!hkey)
2163 break;
2164 db_get_key(hDB, hkey, &key);
2165
2166 /* resolve links */
2167 if (key.type == TID_LINK) {
2169 db_get_key(hDB, hkey, &key);
2170 }
2171
2172 if (key.type == TID_KEY) {
2173 /* for keys, don't display data value */
2174 bout += msprintf("<tr><td colspan=2>%s</td></tr>\n", key.name);
2175 } else {
2176 /* display single value */
2177 if (key.num_values == 1) {
2178 size = sizeof(data);
2179 db_get_data(hDB, hkey, data, &size, key.type);
2180 //printf("data size %d [%s]\n", size, data);
2181 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2182 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2183
2184 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2185 data_str = "(empty)";
2186 hex_str = "";
2187 }
2188
2189 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2190 //sprintf(b, "<tr><td>%s</td><td>%s (%s)</td></tr>\n", key.name, data_str, hex_str);
2191 bout += "<tr><td>";
2192 bout += key.name;
2193 bout += "</td><td>";
2194 bout += data_str;
2195 bout += " (";
2196 bout += hex_str;
2197 bout += ")</td></tr>\n";
2198 } else {
2199 bout += msprintf("<tr><td>%s</td><td>", key.name);
2200 bout += strencode2(data_str.c_str());
2201 bout += "</td></tr>\n";
2202 }
2203 } else {
2204 /* display first value */
2205 bout += msprintf("<tr><td rowspan=%d>%s</td>\n", key.num_values, key.name);
2206
2207 for (j = 0; j < key.num_values; j++) {
2208 size = sizeof(data);
2209 db_get_data_index(hDB, hkey, data, &size, j, key.type);
2210 std::string data_str = db_sprintf(data, key.item_size, 0, key.type);
2211 std::string hex_str = db_sprintfh(data, key.item_size, 0, key.type);
2212
2213 if (data_str.empty() || equal_ustring(data_str.c_str(), "<NULL>")) {
2214 data_str = "(empty)";
2215 hex_str = "";
2216 }
2217
2218 if (j > 0) {
2219 bout += "<tr>";
2220 }
2221
2222 if (strcmp(data_str.c_str(), hex_str.c_str()) != 0 && hex_str[0]) {
2223 //sprintf(b, "<td>[%d] %s (%s)<br></td></tr>\n", j, data_str, hex_str);
2224 bout += "<td>[";
2225 bout += toString(j);
2226 bout += "] ";
2227 bout += data_str;
2228 bout += " (";
2229 bout += hex_str;
2230 bout += ")<br></td></tr>\n";
2231 } else {
2232 //sprintf(b, "<td>[%d] %s<br></td></tr>\n", j, data_str);
2233 bout += "<td>[";
2234 bout += toString(j);
2235 bout += "] ";
2236 bout += data_str;
2237 bout += "<br></td></tr>\n";
2238 }
2239 }
2240 }
2241 }
2242 }
2243
2244 bout += "</table>\n";
2245}
#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:2048
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:7967
int ss_isfin(double x)
Definition system.cxx:7972
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:13814
#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 16184 of file mhttpd.cxx.

16185{
16186 if (!params) {
16187 MJSO *doc = MJSO::I();
16188 doc->D("get current value of mhttpd http_trace");
16189 doc->P(NULL, 0, "there are no input parameters");
16190 doc->R(NULL, MJSON_INT, "current value of http_trace");
16191 return doc;
16192 }
16193
16194 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16195}
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:5851
std::string ss_getcwd()
Definition system.cxx:5776
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 14258 of file mhttpd.cxx.

14259{
14261
14262 decode_cookies(&cookies, msg);
14263
14264 // lock shared structures
14265
14266#ifdef HAVE_MONGOOSE6
14268 assert(status == SS_SUCCESS);
14269#endif
14270
14271 //t->fTimeLocked = GetTimeSec();
14272
14273 // prepare return buffer
14274
14275 Return *rr = new Return();
14276
14277 rr->zero();
14278
14279 // call midas
14280
14281 decode_get(rr, NULL, &cookies, uri, query_string, t);
14282
14283 if (trace_mg)
14284 printf("handle_decode_get: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14285
14287
14288 if (rr->return_length == -1) {
14289 delete rr;
14290#ifdef HAVE_MONGOOSE6
14291 //t->fTimeUnlocked = GetTimeSec();
14293#endif
14294 return RESPONSE_501;
14295 }
14296
14297 if (rr->return_length == 0)
14298 rr->return_length = strlen(rr->return_buffer);
14299
14300 //t->fTimeUnlocked = GetTimeSec();
14301
14302#ifdef HAVE_MONGOOSE6
14304#endif
14305
14306 mg_send(nc, rr->return_buffer, rr->return_length);
14307
14308 if (!strstr(rr->return_buffer, "Content-Length")) {
14309 // cannot do pipelined http if response generated by mhttpd
14310 // decode_get() has no Content-Length header.
14311 // must close the connection.
14313 }
14314
14315 t->fTimeSent = GetTimeSec();
14316
14317 delete rr;
14318
14319 return RESPONSE_SENT;
14320}
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:14256
void decode_cookies(Cookies *c, const http_message *msg)
Definition mhttpd.cxx:14207
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:14254
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 14728 of file mhttpd.cxx.

14729{
14730
14731 char boundary[256];
14732 boundary[0] = 0;
14733 const std::string ct = find_header_mg(msg, "Content-Type");
14734 if (ct.length() > 0) {
14735 const char* s = strstr(ct.c_str(), "boundary=");
14736 if (s)
14737 mstrlcpy(boundary, s+9, sizeof(boundary));
14738 }
14739
14740#ifdef HAVE_MONGOOSE616
14741 if (multithread_mg)
14742 return queue_decode_post(nc, msg, boundary, uri, query_string, t);
14743#endif
14744
14746
14747 decode_cookies(&cookies, msg);
14748
14749 const char* post_data = msg->body.p;
14750 int post_data_len = msg->body.len;
14751
14752 // lock shared strctures
14753
14754#ifdef HAVE_MONGOOSE6
14756 assert(status == SS_SUCCESS);
14757#endif
14758
14759 // prepare return buffer
14760
14761 Return* rr = new Return;
14762
14763 rr->zero();
14764
14765 //printf("post_data_len %d, data [%s], boundary [%s]\n", post_data_len, post_data, boundary);
14766
14767 decode_post(rr, NULL, (char*)post_data, boundary, post_data_len, &cookies, uri, t);
14768
14769 if (trace_mg)
14770 printf("handle_decode_post: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14771
14772 if (rr->return_length == -1) {
14773#ifdef HAVE_MONGOOSE6
14775#endif
14776 delete rr;
14777 return RESPONSE_501;
14778 }
14779
14780 if (rr->return_length == 0)
14781 rr->return_length = strlen(rr->return_buffer);
14782
14783#ifdef HAVE_MONGOOSE6
14785#endif
14786
14787 mg_send(nc, rr->return_buffer, rr->return_length);
14788
14789 if (!strstr(rr->return_buffer, "Content-Length")) {
14790 // cannot do pipelined http if response generated by mhttpd
14791 // decode_get() has no Content-Length header.
14792 // must close the connection.
14794 }
14795
14796 delete rr;
14797
14798 return RESPONSE_SENT;
14799}
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 14173 of file mhttpd.cxx.

14174{
14175 struct mbuf *io = &nc->recv_mbuf;
14176 switch (ev) {
14177 case MG_EV_POLL: // periodic call from loop_mg() via mg_mgr_poll()
14178 break;
14179 case MG_EV_ACCEPT:
14180 if (trace_mg)
14181 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> accept\n", nc, ev, ev_data);
14182 break;
14183 case MG_EV_RECV:
14184 if (trace_mg)
14185 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);
14186#if 0
14187 // This event handler implements simple TCP echo server
14188 mg_send(nc, io->buf, io->len); // Echo received data back
14189 mbuf_remove(io, io->len); // Discard data from recv buffer
14190#endif
14191 break;
14192 case MG_EV_SEND:
14193 if (trace_mg)
14194 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> send %d bytes\n", nc, ev, ev_data, *(int*)ev_data);
14195 break;
14196 case MG_EV_CLOSE:
14197 if (trace_mg)
14198 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> close\n", nc, ev, ev_data);
14199 break;
14200 default:
14201 if (trace_mg)
14202 printf("handle_event_mg: nc %p, ev %d, ev_data %p\n", nc, ev, ev_data);
14203 break;
14204 }
14205}
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 14801 of file mhttpd.cxx.

14802{
14803 std::string query_string = mgstr(&msg->query_string);
14804
14805 if (trace_mg||verbose_mg)
14806 printf("handle_http_get: uri [%s], query [%s]\n", uri, query_string.c_str());
14807
14808 if (query_string == "mjsonrpc_schema") {
14809 MJsonNode* s = mjsonrpc_get_schema();
14810 std::string reply = s->Stringify();
14811 delete s;
14812
14813 int reply_length = reply.length();
14814
14815 const std::string origin_header = find_header_mg(msg, "Origin");
14816
14817 std::string headers;
14818 headers += "HTTP/1.1 200 OK\n";
14819 if (origin_header.length() > 0)
14820 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14821 else
14822 headers += "Access-Control-Allow-Origin: *\n";
14823 headers += "Access-Control-Allow-Credentials: true\n";
14824 headers += "Content-Length: " + toString(reply_length) + "\n";
14825 headers += "Content-Type: application/json\n";
14826 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14827
14828 //printf("sending headers: %s\n", headers.c_str());
14829 //printf("sending reply: %s\n", reply.c_str());
14830
14831 std::string send = headers + "\n" + reply;
14832
14834
14835 mg_send(nc, send.c_str(), send.length());
14836
14837 t->fTimeSent = GetTimeSec();
14838
14839 return RESPONSE_SENT;
14840 }
14841
14842 if (query_string == "mjsonrpc_schema_text") {
14843 MJsonNode* s = mjsonrpc_get_schema();
14844 std::string reply = mjsonrpc_schema_to_text(s);
14845 delete s;
14846
14847 int reply_length = reply.length();
14848
14849 const std::string origin_header = find_header_mg(msg, "Origin");
14850
14851 std::string headers;
14852 headers += "HTTP/1.1 200 OK\n";
14853 if (origin_header.length() > 0)
14854 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14855 else
14856 headers += "Access-Control-Allow-Origin: *\n";
14857 headers += "Access-Control-Allow-Credentials: true\n";
14858 headers += "Content-Length: " + toString(reply_length) + "\n";
14859 headers += "Content-Type: text/plain\n";
14860 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14861
14862 //printf("sending headers: %s\n", headers.c_str());
14863 //printf("sending reply: %s\n", reply.c_str());
14864
14865 std::string send = headers + "\n" + reply;
14866
14868
14869 mg_send(nc, send.c_str(), send.length());
14870
14871 t->fTimeSent = GetTimeSec();
14872
14873 return RESPONSE_SENT;
14874 }
14875
14876#ifdef HAVE_MONGOOSE616
14877 if (multithread_mg)
14878 return queue_decode_get(nc, msg, uri, query_string.c_str(), t);
14879#endif
14880
14881 return handle_decode_get(nc, msg, uri, query_string.c_str(), t);
14882}
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:14258
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 15080 of file mhttpd.cxx.

15081{
15082 std::string method = mgstr(&msg->method);
15083 std::string query_string = mgstr(&msg->query_string);
15084 std::string uri_encoded = mgstr(&msg->uri);
15085 std::string uri = UrlDecode(uri_encoded.c_str());
15086
15087 if (trace_mg)
15088 printf("handle_http_message: method [%s] uri [%s] proto [%s]\n", method.c_str(), uri.c_str(), mgstr(&msg->proto).c_str());
15089
15090 RequestTrace* t = new RequestTrace;
15092 t->fMethod = method;
15093 t->fUri = uri;
15094 t->fQuery = query_string;
15095
15096 // process OPTIONS for Cross-origin (CORS) preflight request
15097 // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
15098 if (method == "OPTIONS" && query_string == "mjsonrpc" && mg_get_http_header(msg, "Access-Control-Request-Method") != NULL) {
15099 handle_http_options_cors(nc, msg, t);
15100 t->fCompleted = true;
15102 return;
15103 }
15104
15106 std::string username = check_digest_auth(msg, gAuthMg);
15107
15108 // Cannot re-read the password file - it is not thread safe to do so
15109 // unless I lock gAuthMg for each call check_digest_auth() and if I do so,
15110 // I will serialize (single-thread) all the http requests and defeat
15111 // the whole point of multithreading the web server. K.O.
15112 //
15114 //if (username.length() < 1) {
15115 // bool ok = read_passwords(&gAuthMg);
15116 // if (ok)
15117 // username = check_digest_auth(msg, &gAuthMg);
15118 //}
15119
15120 if (trace_mg)
15121 printf("handle_http_message: auth user: \"%s\"\n", username.c_str());
15122
15123 if (username.length() == 0) {
15124 if (trace_mg||verbose_mg)
15125 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());
15126
15128 t->fCompleted = true;
15130 return;
15131 }
15132 t->fAuthOk = true;
15133 } else {
15134 t->fAuthOk = true;
15135 }
15136
15137#ifdef HAVE_MONGOOSE616
15138 if (gProxyOdb && starts_with(uri, "/proxy/")) {
15139 std::string::size_type p1 = uri.find("/", 1);
15140 if (p1 == uri.length()-1) {
15141 std::string response = "404 Not Found (Proxy name is missing)";
15142 mg_send_head(nc, 404, response.length(), NULL);
15143 mg_send(nc, response.c_str(), response.length());
15144 delete t;
15145 return;
15146 }
15147 std::string::size_type p2 = uri.find("/", p1+1);
15148 if (p2 == std::string::npos) {
15149 std::string response = "404 Not Found (Proxy URL should end with a slash)";
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 p = uri.substr(p1+1, p2-p1-1);
15156 //printf("uri [%s], p1: %d, p2: %d, substr: [%s]\n", uri.c_str(), (int)p1, (int)p2, p.c_str());
15157 if (p.length() < 1) {
15158 std::string response = "404 Not Found (Double-slash or Proxy name is too short)";
15159 mg_send_head(nc, 404, response.length(), NULL);
15160 mg_send(nc, response.c_str(), response.length());
15161 delete t;
15162 return;
15163 }
15164 std::string destination;
15165 gProxyOdb->RS(p.c_str(), &destination);
15166 if (destination.length() < 1) {
15167 std::string response = "404 Not Found (Proxy not found in ODB)";
15168 mg_send_head(nc, 404, response.length(), NULL);
15169 mg_send(nc, response.c_str(), response.length());
15170 delete t;
15171 return;
15172 } else if (destination[0] == '#') {
15173 std::string response = "404 Not Found (Proxy commented-out in ODB)";
15174 mg_send_head(nc, 404, response.length(), NULL);
15175 mg_send(nc, response.c_str(), response.length());
15176 delete t;
15177 return;
15178 } else if (ends_with_char(destination, '/')) {
15179 std::string response = "404 Not Found (Proxy address should not end with a slash)";
15180 mg_send_head(nc, 404, response.length(), NULL);
15181 mg_send(nc, response.c_str(), response.length());
15182 delete t;
15183 return;
15184 } else if (!starts_with(destination, "http")) {
15185 std::string response = "404 Not Found (Proxy address does not start with http";
15186 mg_send_head(nc, 404, response.length(), NULL);
15187 mg_send(nc, response.c_str(), response.length());
15188 delete t;
15189 return;
15190 } else {
15191 std::string m;
15192 m += "/proxy";
15193 m += "/";
15194 m += p;
15195 mg_str mount = mg_mk_str(m.c_str());
15197 if (verbose_mg||trace_mg) {
15198 printf("proxy: uri [%s] mount [%s] upstream [%s]\n", uri.c_str(), mgstr(&mount).c_str(), mgstr(&upstream).c_str());
15199 }
15201 delete t;
15202 return;
15203 }
15204 }
15205#endif
15206
15207 int response = RESPONSE_501;
15208
15209 if (method == "GET")
15210 response = handle_http_get(nc, msg, uri.c_str(), t);
15211 else if (method == "POST")
15212 response = handle_http_post(nc, msg, uri.c_str(), t);
15213
15214 if (response == RESPONSE_501) {
15215 if (trace_mg||verbose_mg)
15216 printf("handle_http_message: sending 501 Not Implemented error\n");
15217
15218 std::string response = "501 Not Implemented";
15219 mg_send_head(nc, 501, response.length(), NULL); // 501 Not Implemented
15220 mg_send(nc, response.c_str(), response.length());
15221 }
15222
15223 if (response != RESPONSE_QUEUED) {
15224 t->fCompleted = true;
15226 }
15227}
std::string realm
Definition mhttpd.cxx:13725
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:14884
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:13893
static std::string UrlDecode(const char *p)
Definition mhttpd.cxx:841
bool starts_with(const std::string &s1, const char *s2)
Definition mhttpd.cxx:4428
#define RESPONSE_QUEUED
Definition mhttpd.cxx:14255
static int handle_http_get(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14801
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:13787
static void handle_http_options_cors(struct mg_connection *nc, const http_message *msg, RequestTrace *t)
Definition mhttpd.cxx:15010
static Auth * gAuthMg
Definition mhttpd.cxx:13753
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 15010 of file mhttpd.cxx.

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

14885{
14886 std::string query_string = mgstr(&msg->query_string);
14887 std::string post_data = mgstr(&msg->body);
14888
14889 if (trace_mg||verbose_mg)
14890 printf("handle_http_post: uri [%s], query [%s], post data %d bytes\n", uri, query_string.c_str(), (int)post_data.length());
14891 if (trace_mg_verbose)
14892 printf("handle_http_post: post data = \n%s\n", post_data.c_str());
14893
14894 if (query_string.substr(0, 8) == "mjsonrpc") { // ignore any parameter after "mjsonrpc"
14895 const std::string origin_header = find_header_mg(msg, "Origin");
14896 const std::string ctype_header = find_header_mg(msg, "Content-Type");
14897
14898 if (strstr(ctype_header.c_str(), "application/json") == NULL) {
14899 std::string headers;
14900 headers += "HTTP/1.1 415 Unsupported Media Type\n";
14901 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14902
14903 //printf("sending headers: %s\n", headers.c_str());
14904 //printf("sending reply: %s\n", reply.c_str());
14905
14906 if (trace_mg_verbose)
14907 printf("handle_http_post: unsupported media type \"%s\"\n", ctype_header.c_str());
14908
14909 std::string send = headers + "\n";
14910
14912
14913 mg_send(nc, send.c_str(), send.length());
14914
14915 t->fTimeSent = GetTimeSec();
14916
14917 return RESPONSE_SENT;
14918 }
14919
14920#ifdef HAVE_MONGOOSE616
14921 if (multithread_mg)
14922 return queue_mjsonrpc(nc, origin_header, post_data, t);
14923#endif
14924
14925 //printf("post body: %s\n", post_data.c_str());
14926
14927 t->fRPC = post_data;
14928
14929#ifdef HAVE_MONGOOSE6
14931 assert(status == SS_SUCCESS);
14932#endif
14933
14934 //t->fTimeLocked = GetTimeSec();
14935
14936 MJsonNode* reply = mjsonrpc_decode_post_data(post_data.c_str());
14937
14938 //t->fTimeUnlocked = GetTimeSec();
14939
14940#ifdef HAVE_MONGOOSE6
14942#endif
14943
14944 if (reply->GetType() == MJSON_ARRAYBUFFER) {
14945 const char* ptr;
14946 size_t size;
14947 reply->GetArrayBuffer(&ptr, &size);
14948
14949 std::string headers;
14950 headers += "HTTP/1.1 200 OK\n";
14951 if (origin_header.length() > 0)
14952 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14953 else
14954 headers += "Access-Control-Allow-Origin: *\n";
14955 headers += "Access-Control-Allow-Credentials: true\n";
14956 headers += "Content-Length: " + toString(size) + "\n";
14957 headers += "Content-Type: application/octet-stream\n";
14958 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14959
14960 //printf("sending headers: %s\n", headers.c_str());
14961 //printf("sending reply: %s\n", reply_string.c_str());
14962
14963 std::string send = headers + "\n";
14964
14966
14967 mg_send(nc, send.c_str(), send.length());
14968 mg_send(nc, ptr, size);
14969
14970 t->fTimeSent = GetTimeSec();
14971
14972 delete reply;
14973
14974 return RESPONSE_SENT;
14975 }
14976
14977 std::string reply_string = reply->Stringify();
14978 int reply_length = reply_string.length();
14979
14980 std::string headers;
14981 headers += "HTTP/1.1 200 OK\n";
14982 if (origin_header.length() > 0)
14983 headers += "Access-Control-Allow-Origin: " + std::string(origin_header) + "\n";
14984 else
14985 headers += "Access-Control-Allow-Origin: *\n";
14986 headers += "Access-Control-Allow-Credentials: true\n";
14987 headers += "Content-Length: " + toString(reply_length) + "\n";
14988 headers += "Content-Type: application/json\n";
14989 //headers += "Date: Sat, 08 Jul 2006 12:04:08 GMT\n";
14990
14991 //printf("sending headers: %s\n", headers.c_str());
14992 //printf("sending reply: %s\n", reply_string.c_str());
14993
14994 std::string send = headers + "\n" + reply_string;
14995
14997
14998 mg_send(nc, send.c_str(), send.length());
14999
15000 t->fTimeSent = GetTimeSec();
15001
15002 delete reply;
15003
15004 return RESPONSE_SENT;
15005 }
15006
15007 return handle_decode_post(nc, msg, uri, query_string.c_str(), t);
15008}
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:14728
static bool trace_mg_verbose
Definition mhttpd.cxx:13708
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 1979 of file mhttpd.cxx.

1980{
1981 HNDLE hDB;
1982 int size;
1983 HNDLE hkey;
1985
1987 std::string external_elog_url;
1988
1989 size = sizeof(external_elog);
1990 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
1991 db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
1992
1995 size = sizeof(BOOL);
1996 db_get_value(hDB, 0, "/Elog/Allow delete", &allow_delete, &size, TID_BOOL, TRUE);
1997 db_get_value(hDB, 0, "/Elog/Allow edit", &allow_edit, &size, TID_BOOL, TRUE);
1998 //db_get_value(hDB, 0, "/Elog/Display run number", &display_run_number, &size, TID_BOOL, TRUE);
1999
2000 if (db_find_key(hDB, 0, "/Elog/Buttons", &hkey) != DB_SUCCESS) {
2001 const char def_button[][NAME_LENGTH] = { "8h", "24h", "7d" };
2002 db_set_value(hDB, 0, "/Elog/Buttons", def_button, NAME_LENGTH*3, 3, TID_STRING);
2003 }
2004
2005
2006 /* get type list from ODB */
2007 size = 20 * NAME_LENGTH;
2008 if (db_find_key(hDB, 0, "/Elog/Types", &hkey) != DB_SUCCESS) {
2009 db_set_value(hDB, 0, "/Elog/Types", default_type_list, NAME_LENGTH * 20, 20, TID_STRING);
2010 }
2011
2012 /* get system list from ODB */
2013 size = 20 * NAME_LENGTH;
2014 if (db_find_key(hDB, 0, "/Elog/Systems", &hkey) != DB_SUCCESS)
2015 db_set_value(hDB, 0, "/Elog/Systems", default_system_list, NAME_LENGTH * 20, 20, TID_STRING);
2016}
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/PySequencer",&true_value, &size, TID_BOOL, TRUE);
1913 db_get_value(hDB, 0, "/Experiment/Menu/Event Dump", &true_value, &size, TID_BOOL, TRUE);
1914 db_get_value(hDB, 0, "/Experiment/Menu/Config", &true_value, &size, TID_BOOL, TRUE);
1915 db_get_value(hDB, 0, "/Experiment/Menu/Example", &false_value, &size, TID_BOOL, TRUE);
1916 db_get_value(hDB, 0, "/Experiment/Menu/Help", &true_value, &size, TID_BOOL, TRUE);
1917
1918 //std::string buf;
1919 //status = db_get_value_string(hDB, 0, "/Experiment/Menu buttons", 0, &buf, FALSE);
1920 //if (status == DB_SUCCESS) {
1921 // cm_msg(MERROR, "init_menu_buttons", "ODB \"/Experiment/Menu buttons\" is obsolete, please delete it.");
1922 //}
1923
1924 check_obsolete_odb(hDB, "/Experiment/Menu buttons");
1925 check_obsolete_odb(hDB, "/Experiment/Menu/OldSequencer");
1926 check_obsolete_odb(hDB, "/Experiment/Menu/NewSequencer");
1927}
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 1931 of file mhttpd.cxx.

1932{
1933 HNDLE hDB;
1934 HNDLE hKey;
1935 int status;
1936 std::string s;
1938
1939 status = db_find_key(hDB, 0, "/Experiment/Base URL", &hKey);
1940 if (status == DB_SUCCESS) {
1941 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Base URL\" is obsolete, please delete it.");
1942 }
1943
1944 status = db_find_key(hDB, 0, "/Experiment/CSS File", &hKey);
1945 if (status == DB_SUCCESS) {
1946 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/CSS File\" is obsolete, please delete it.");
1947 }
1948
1949 status = db_find_key(hDB, 0, "/Experiment/JS File", &hKey);
1950 if (status == DB_SUCCESS) {
1951 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/JS File\" is obsolete, please delete it.");
1952 }
1953
1954 status = db_find_key(hDB, 0, "/Experiment/Start-Stop Buttons", &hKey);
1955 if (status == DB_SUCCESS) {
1956 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Start-Stop Buttons\" is obsolete, please delete it.");
1957 }
1958
1959 bool xdefault = true;
1960 odb->RB("Experiment/Pause-Resume Buttons", &xdefault, true);
1961
1962#ifdef HAVE_MONGOOSE616
1963 check_obsolete_odb(hDB, "/Experiment/midas http port");
1964 check_obsolete_odb(hDB, "/Experiment/midas https port");
1965 check_obsolete_odb(hDB, "/Experiment/http redirect to https");
1966 check_obsolete_odb(hDB, "/Experiment/Security/mhttpd hosts");
1967#endif
1968
1969 status = db_find_key(hDB, 0, "/Logger/Message file", &hKey);
1970 if (status == DB_SUCCESS) {
1971 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.");
1972 }
1973
1974 check_obsolete_odb(hDB, "/Logger/Watchdog timeout");
1975}
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:75
int cm_exec_script(const char *odb_path_to_script)
Definition midas.cxx:5469
INT cm_exist(const char *name, BOOL bUnique)
Definition midas.cxx:7528
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:7124
char * ss_crypt(const char *buf, const char *salt)
Definition system.cxx:7897
#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:2559
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:2249
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:5654
void javascript_commands(Param *p, Return *r, const char *cookie_cpwd)
Definition mhttpd.cxx:4444
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:2484
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:3571
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:5420
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:3673
#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 2532 of file mhttpd.cxx.

2533{
2534 HNDLE hDB, hkey;
2535 KEY key;
2536 char str[256];
2537 int i, size;
2538
2540 sprintf(str, "/Equipment/%s/Settings/Editable", eq_name);
2541 db_find_key(hDB, 0, str, &hkey);
2542
2543 /* if no editable entry found, use default */
2544 if (!hkey) {
2545 return (equal_ustring(var_name, "Demand") ||
2546 equal_ustring(var_name, "Output") || strncmp(var_name, "D_", 2) == 0);
2547 }
2548
2549 db_get_key(hDB, hkey, &key);
2550 for (i = 0; i < key.num_values; i++) {
2551 size = sizeof(str);
2554 return TRUE;
2555 }
2556 return FALSE;
2557}
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 4444 of file mhttpd.cxx.

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

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

14138{
14139 return std::string(s->p, s->len);
14140}
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:7718
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 4369 of file mhttpd.cxx.

4370{
4371 int size, i;
4372 HNDLE hDB, hsubkey;
4373 KEY key;
4374 char data[TEXT_SIZE];
4375
4377
4378 db_get_key(hDB, hkey, &key);
4379 if (key.type == TID_KEY) {
4380 for (i=0 ; ; i++) {
4382 if (!hsubkey)
4383 break;
4384 output_key(p, r, hsubkey, -1, format);
4385 }
4386 } else {
4387 if (key.item_size <= (int)sizeof(data)) {
4388 size = sizeof(data);
4389 db_get_data(hDB, hkey, data, &size, key.type);
4390 if (index == -1) {
4391 for (i=0 ; i<key.num_values ; i++) {
4392 if (p->isparam("name") && atoi(p->getparam("name")) == 1) {
4393 if (key.num_values == 1)
4394 r->rsprintf("%s:", key.name);
4395 else
4396 r->rsprintf("%s[%d]:", key.name, i);
4397 }
4398 std::string data_str;
4399 if (format && format[0])
4401 else
4403 r->rsputs(data_str.c_str());
4404 if (i<key.num_values-1)
4405 r->rsputs("\n");
4406 }
4407 } else {
4408 if (p->isparam("name") && atoi(p->getparam("name")) == 1)
4409 r->rsprintf("%s[%d]:", key.name, index);
4410 if (index >= key.num_values)
4411 r->rsputs("<DB_OUT_OF_RANGE>");
4412 else {
4413 std::string data_str;
4414 if (p->isparam("format"))
4416 else
4418 r->rsputs(data_str.c_str());
4419 }
4420 }
4421 r->rsputs("\n");
4422 }
4423 }
4424}
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 13797 of file mhttpd.cxx.

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

16198{
16199 if (!params) {
16200 MJSO* doc = MJSO::I();
16201 doc->D("set new value of mhttpd http_trace");
16202 doc->P(NULL, MJSON_INT, "new value of http_trace");
16203 doc->R(NULL, MJSON_INT, "new value of http_trace");
16204 return doc;
16205 }
16206
16207 http_trace = params->GetInt();
16208 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16209}
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 5654 of file mhttpd.cxx.

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

3611{
3612 char str[256];
3613 std::string filename;
3614 HNDLE hDB;
3615
3617
3618 HNDLE hkey;
3619 sprintf(str, "/Custom/%s", name);
3620 db_find_key(hDB, 0, str, &hkey);
3621
3622 if (!hkey) {
3623 sprintf(str, "/Custom/%s&", name);
3624 db_find_key(hDB, 0, str, &hkey);
3625 if (!hkey) {
3626 sprintf(str, "/Custom/%s!", name);
3627 db_find_key(hDB, 0, str, &hkey);
3628 }
3629 }
3630
3631 if(!hkey){
3632 sprintf(str,"show_custom_file: Invalid custom page: \"/Custom/%s\" not found in ODB", name);
3633 show_error_404(r, str);
3634 return;
3635 }
3636
3637 int status;
3638 KEY key;
3639
3641
3642 if (status != DB_SUCCESS) {
3643 char errtext[512];
3644 sprintf(errtext, "show_custom_file: Error: db_get_key() for \"%s\" status %d", str, status);
3646 return;
3647 }
3648
3649 int size = key.total_size;
3650 char* ctext = (char*)malloc(size);
3651
3653
3654 if (status != DB_SUCCESS) {
3655 char errtext[512];
3656 sprintf(errtext, "show_custom_file: Error: db_get_data() for \"%s\" status %d", str, status);
3658 free(ctext);
3659 return;
3660 }
3661
3662 filename = add_custom_path(ctext);
3663
3664 free(ctext);
3665
3666 send_file(r, filename, true);
3667
3668 return;
3669}
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 3673 of file mhttpd.cxx.

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

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

2485{
2486 HNDLE hDB;
2487 int size;
2488 int status;
2489 char file_name[256];
2490
2492 file_name[0] = 0;
2493 if (hDB > 0) {
2494 size = sizeof(file_name);
2495 memset(file_name, 0, size);
2496
2497 status = db_get_value(hDB, 0, "/Logger/Elog dir", file_name, &size, TID_STRING, FALSE);
2498 if (status != DB_SUCCESS)
2499 db_get_value(hDB, 0, "/Logger/Data dir", file_name, &size, TID_STRING, TRUE);
2500
2501 if (file_name[0] != 0)
2504 }
2505 mstrlcat(file_name, path, sizeof(file_name));
2506
2507 int fh = open(file_name, O_RDONLY | O_BINARY);
2508 if (fh > 0) {
2509 lseek(fh, 0, SEEK_END);
2510 int length = TELL(fh);
2511 lseek(fh, 0, SEEK_SET);
2512
2513 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
2514 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
2515 r->rsprintf("Accept-Ranges: bytes\r\n");
2516 //r->rsprintf("Content-disposition: attachment; filename=%s\r\n", path);
2517
2518 r->rsprintf("Content-Type: %s\r\n", get_content_type(file_name).c_str());
2519
2520 r->rsprintf("Content-Length: %d\r\n\r\n", length);
2521
2522 r->rread(file_name, fh, length);
2523
2524 close(fh);
2525 }
2526
2527 return;
2528}
#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 2559 of file mhttpd.cxx.

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

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

4429{
4430 if (s1.length() < strlen(s2))
4431 return false;
4432 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4433}
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 2020 of file mhttpd.cxx.

2021{
2022 size_t len = strlen(text);
2023 for (size_t i = 0; i < len; i++) {
2024 switch (text[i]) {
2025 case '\n':
2026 r->rsprintf("<br>\n");
2027 break;
2028 case '<':
2029 r->rsprintf("&lt;");
2030 break;
2031 case '>':
2032 r->rsprintf("&gt;");
2033 break;
2034 case '&':
2035 r->rsprintf("&amp;");
2036 break;
2037 case '\"':
2038 r->rsprintf("&quot;");
2039 break;
2040 default:
2041 r->rsprintf("%c", text[i]);
2042 }
2043 }
2044}
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 2048 of file mhttpd.cxx.

2049{
2050 std::string b;
2051 size_t len = strlen(text);
2052 for (size_t i = 0; i < len; i++) {
2053 switch (text[i]) {
2054 case '\n':
2055 b += "<br>\n";
2056 break;
2057 case '<':
2058 b += "&lt;";
2059 break;
2060 case '>':
2061 b += "&gt;";
2062 break;
2063 case '&':
2064 b += "&amp;";
2065 break;
2066 case '\"':
2067 b += "&quot;";
2068 break;
2069 default:
2070 b += text[i];
2071 break;
2072 }
2073 }
2074 return b;
2075}
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 2079 of file mhttpd.cxx.

2080{
2081 size_t len = strlen(text);
2082 for (size_t i = 0; i < len; i++) {
2083 switch (text[i]) {
2084 case '<':
2085 r->rsprintf("&lt;");
2086 break;
2087 case '>':
2088 r->rsprintf("&gt;");
2089 break;
2090 case '&':
2091 r->rsprintf("&amp;");
2092 break;
2093 case '\"':
2094 r->rsprintf("&quot;");
2095 break;
2096 default:
2097 r->rsprintf("%c", text[i]);
2098 }
2099 }
2100}
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 2104 of file mhttpd.cxx.

2105{
2106 size_t len = strlen(text);
2107 for (size_t i = 0; i < len; i++) {
2108 switch (text[i]) {
2109 case '\n':
2110 r->rsprintf("<br>\n");
2111 break;
2112 case '<':
2113 r->rsprintf("&lt;");
2114 break;
2115 case '>':
2116 r->rsprintf("&gt;");
2117 break;
2118 case '&':
2119 r->rsprintf("&amp;");
2120 break;
2121 case '\"':
2122 r->rsprintf("&quot;");
2123 break;
2124 case ' ':
2125 r->rsprintf("&nbsp;");
2126 break;
2127 default:
2128 r->rsprintf("%c", text[i]);
2129 }
2130 }
2131}
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 2249 of file mhttpd.cxx.

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

13776 {
13777 unsigned long now = (unsigned long) time(NULL);
13778 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13779 return now < val || now - val < 3600;
13780}
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 13787 of file mhttpd.cxx.

13788 {
13789 mg_printf(c,
13790 "HTTP/1.1 401 Unauthorized\r\n"
13791 "WWW-Authenticate: Digest qop=\"auth\", "
13792 "realm=\"%s\", nonce=\"%lu\"\r\n"
13793 "Content-Length: 0\r\n\r\n",
13794 domain, (unsigned long) time(NULL));
13795}
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 13755 of file mhttpd.cxx.

13759 {
13760 static const char colon[] = ":";
13761 static const size_t one = 1;
13762 char ha2[33];
13763
13764 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13765 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13766 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13767 colon, one, ha2, sizeof(ha2) - 1, NULL);
13768}
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 3469 of file mhttpd.cxx.

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

◆ 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 3429 of file mhttpd.cxx.

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

◆ 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 13753 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.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

Definition at line 13708 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.