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 OBSOLETE   1
 
#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 8244 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 8245 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 8246 of file mhttpd.cxx.

◆ HTTP_ENCODING

#define HTTP_ENCODING   "UTF-8"

Definition at line 213 of file mhttpd.cxx.

◆ LN10

#define LN10   2.302585094

Definition at line 7638 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7639 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

Definition at line 7640 of file mhttpd.cxx.

◆ MAX_GROUPS

#define MAX_GROUPS   32

Definition at line 52 of file mhttpd.cxx.

◆ MAX_PARAM

#define MAX_PARAM   500

Definition at line 697 of file mhttpd.cxx.

◆ MAX_VARS

#define MAX_VARS   100

Definition at line 53 of file mhttpd.cxx.

◆ OBSOLETE

#define OBSOLETE   1

Definition at line 45 of file mhttpd.cxx.

◆ PARAM_LENGTH

#define PARAM_LENGTH   256

Definition at line 698 of file mhttpd.cxx.

◆ READ_HISTORY_DATA

#define READ_HISTORY_DATA   0x1

Definition at line 8330 of file mhttpd.cxx.

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8332 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8331 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14272 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14271 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14270 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

Definition at line 8247 of file mhttpd.cxx.

◆ TEXT_SIZE

#define TEXT_SIZE   50000

Definition at line 699 of file mhttpd.cxx.

◆ WEB_BUFFER_SIZE

#define WEB_BUFFER_SIZE   (6*1024*1024)

Definition at line 511 of file mhttpd.cxx.

Function Documentation

◆ add_custom_path()

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

Definition at line 3575 of file mhttpd.cxx.

3576{
3577 // do not append custom path to absolute filenames
3578
3579 if (filename[0] == '/')
3580 return filename;
3581 if (filename[0] == DIR_SEPARATOR)
3582 return filename;
3583
3584 HNDLE hDB;
3586
3587 std::string custom_path = "";
3588
3589 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3590
3591 if (status != DB_SUCCESS)
3592 return filename;
3593
3594 if (custom_path.length() < 1)
3595 return filename;
3596
3598 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3599 return filename;
3600 }
3601
3603
3604 std::string full_filename = custom_path;
3605 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3607 full_filename += filename;
3608
3609 return full_filename;
3610}
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3025
#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:2284
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:929
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:13945
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 9790 of file mhttpd.cxx.

9791{
9792 std::string s;
9793 s += name; // FIXME: should be URI-encoded
9794 s += "=";
9795 s += value; // FIXME: should be URI-encoded
9796 return s;
9797}
#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 16227 of file mhttpd.cxx.

16228{
16229 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16230 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16231}
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:16200
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16213
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 10387 of file mhttpd.cxx.

10388{
10389 int seln = atoi(p->getparam("seln"));
10390 for (int i=0; i<seln; i++) {
10391 char str[256];
10392 sprintf(str, "sel%d", i);
10393
10394 std::string par = p->getparam(str);
10395 if (par.length() < 1)
10396 continue;
10397
10398 std::string event_name, tag_name;
10399 SplitEventAndTagNames(par, event_name, tag_name);
10400
10401 if (tag_name == "")
10402 continue;
10403
10404 HistVar v;
10405
10406 v.event_name = event_name;
10407 v.tag_name = tag_name;
10410
10411 hp.vars.push_back(v);
10412 }
10413}
const char * getparam(const char *param)
Definition mhttpd.cxx:776
INT i
Definition mdump.cxx:32
static void SplitEventAndTagNames(std::string var_name, std::string &event_name, std::string &tag_name)
Definition mhttpd.cxx:10161
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10126
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10152
char str[256]
Definition odbhist.cxx:33
std::string tag_name
Definition mhttpd.cxx:8337
int order
Definition mhttpd.cxx:8342
std::string colour
Definition mhttpd.cxx:8339
std::string event_name
Definition mhttpd.cxx:8336
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 13909 of file mhttpd.cxx.

13910{
13911 char expected_response[33];
13912
13913 //printf("HereA!\n");
13914
13915 /* Parse "Authorization:" header, fail fast on parse error */
13916 struct mg_str *hdr = mg_get_http_header(hm, "Authorization");
13917
13918 if (!hdr)
13919 return "";
13920
13921 //printf("HereB!\n");
13922
13923 std::string user = find_var_mg(hdr, "username");
13924 std::string cnonce = find_var_mg(hdr, "cnonce");
13925 std::string response = find_var_mg(hdr, "response");
13926 std::string uri = find_var_mg(hdr, "uri");
13927 std::string qop = find_var_mg(hdr, "qop");
13928 std::string nc = find_var_mg(hdr, "nc");
13929 std::string nonce = find_var_mg(hdr, "nonce");
13930
13931 if (user.length()<1) return "";
13932 if (cnonce.length()<1) return "";
13933 if (response.length()<1) return "";
13934 if (uri.length()<1) return "";
13935 if (qop.length()<1) return "";
13936 if (nc.length()<1) return "";
13937 if (nonce.length()<1) return "";
13938
13939 if (xmg_check_nonce(nonce.c_str()) == 0) return "";
13940 //printf("HereB8!\n");
13941
13942 //printf("HereC!\n");
13943
13944 const char* uri_end = strchr(hm->uri.p, ' ');
13945 if (!uri_end) return "";
13946
13947 size_t uri_length = uri_end - hm->uri.p;
13948
13949 if (uri_length != uri.length())
13950 return "";
13951
13952 int cmp = strncmp(hm->uri.p, uri.c_str(), uri_length);
13953
13954 //printf("check URI: message %d %d [%d] authorization [%s]\n", (int)hm->uri.len, uri_length, cmp, uri);
13955
13956 if (cmp != 0)
13957 return "";
13958
13959 for (unsigned i=0; i<auth->passwords.size(); i++) {
13960 AuthEntry* e = &auth->passwords[i];
13961 if (e->username != user)
13962 continue;
13963 if (e->realm != auth->realm)
13964 continue;
13965 const char* f_ha1 = e->password.c_str();
13966 int uri_len = hm->uri.len;
13967 if (hm->uri.p[uri_len] == '?')
13968 uri_len += hm->query_string.len + 1; // "+1" accounts for the "?" character
13969 xmg_mkmd5resp(hm->method.p, hm->method.len,
13970 hm->uri.p, uri_len,
13971 f_ha1, strlen(f_ha1),
13972 nonce.c_str(), nonce.length(),
13973 nc.c_str(), nc.length(),
13974 cnonce.c_str(), cnonce.length(),
13975 qop.c_str(), qop.length(),
13977 int cmp = strcasecmp(response.c_str(), expected_response);
13978 //printf("digest_auth: expected %s, got %s, cmp %d\n", expected_response, response.c_str(), cmp);
13979 if (cmp == 0) {
13980 return e->username;
13981 }
13982 }
13983
13984 return "";
13985}
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:13771
static int xmg_check_nonce(const char *nonce)
Definition mhttpd.cxx:13792
Definition mhttpd.cxx:13733
std::string password
Definition mhttpd.cxx:13736
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 1883 of file mhttpd.cxx.

1884{
1885 HNDLE hKey;
1886 int status = db_find_key(hDB, 0, odb_path, &hKey);
1887 if (status == DB_SUCCESS) {
1888 cm_msg(MERROR, "check_obsolete_odb", "ODB \"%s\" is obsolete, please delete it.", odb_path);
1889 }
1890}
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4084
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 13405 of file mhttpd.cxx.

13406{
13407 HNDLE hDB, hKeyEq, hKey;
13409 int i, status;
13410 KEY key;
13411
13412 /* check /Runinfo structure */
13414 assert(status == DB_SUCCESS);
13415
13416 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13417 if (status == DB_STRUCT_MISMATCH) {
13418 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13419 if (status == DB_SUCCESS) {
13420 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13421 } else {
13422 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13423 return 0;
13424 }
13425 } else if (status == DB_NO_KEY) {
13426 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13427 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13428 if (status == DB_SUCCESS) {
13429 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13430 } else {
13431 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13432 return 0;
13433 }
13434 } else if (status != DB_SUCCESS) {
13435 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13436 return 0;
13437 }
13438
13439 /* check /Equipment/<name>/Common structures */
13440 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13441 for (i = 0 ;; i++) {
13443 if (!hKey)
13444 break;
13445 db_get_key(hDB, hKey, &key);
13446
13448 if (status == DB_STRUCT_MISMATCH) {
13450 if (status == DB_SUCCESS) {
13451 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13452 } else {
13453 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13454 }
13455 } else if (status != DB_SUCCESS) {
13456 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13457 }
13458 }
13459 }
13460
13461 return CM_SUCCESS;
13462}
#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:600
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:12981
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6024
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5591
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12808
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 6746 of file mhttpd.cxx.

6747{
6748 HNDLE hkey;
6749 INT size;
6750 char str[256];
6751
6752 /* check for password */
6753 db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hkey);
6754 if (hkey) {
6755 size = sizeof(str);
6756 db_get_data(hDB, hkey, str, &size, TID_STRING);
6757 if (strcmp(password, str) == 0)
6758 return TRUE;
6759
6760 /* show web password page */
6761 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6762 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6763 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6764
6765 r->rsprintf("<html><head>\n");
6766 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6767 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6768 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6769 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6770
6771 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6772
6773 /* define hidden fields for current experiment and destination */
6774 if (redir[0])
6775 r->rsprintf("<input type=hidden name=redir value=\"%s\">\n", redir);
6776
6777 /*---- page header ----*/
6778 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6779
6780 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6781
6782 if (password[0])
6783 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6784
6785 r->rsprintf
6786 ("<tr><th>Please enter password to obtain write access</tr>\n");
6787 r->rsprintf("<tr><td align=center><input type=password name=wpwd></tr>\n");
6788 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6789
6790 r->rsprintf("</table>\n");
6791
6792 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6793 r->rsprintf("</form>\n");
6794 r->rsprintf("</body></html>\r\n");
6795
6796 return FALSE;
6797 } else
6798 return TRUE;
6799}
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:6544
#define HTTP_ENCODING
Definition mhttpd.cxx:213
const char * mhttpd_revision(void)
Definition mhttpd.cxx:836
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 10043 of file mhttpd.cxx.

10044{
10045 return cmp_names(a.c_str(), b.c_str()) < 0;
10046}
static int cmp_names(const void *a, const void *b)
Definition mhttpd.cxx:9985
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 10048 of file mhttpd.cxx.

10049{
10050 return a < b;
10051}
Here is the caller graph for this function:

◆ cmp_names()

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

Definition at line 9985 of file mhttpd.cxx.

9986{
9987 int i;
9988 const char*sa = (const char*)a;
9989 const char*sb = (const char*)b;
9990
9991 int debug = 0;
9992
9993 // Cannot use strcmp() because it does not know how to compare numerical values, e.g.
9994 // it thinks "111" is smaller than "9"
9995 //return strcmp(sa, sb);
9996
9997 if (debug)
9998 printf("compare [%s] and [%s]\n", sa, sb);
9999
10000 for (i=0; ; i++) {
10001 if (sa[i]==0 && sb[i]==0)
10002 return 0; // both strings have the same length and the same characters
10003
10004 //printf("index %d, char [%c] [%c], isdigit %d %d\n", i, sa[i], sb[i], isdigit(sa[i]), isdigit(sb[i]));
10005
10006 if (isdigit(sa[i]) && isdigit(sb[i])) {
10007 int va = atoi(sa+i);
10008 int vb = atoi(sb+i);
10009
10010 if (debug)
10011 printf("index %d, values %d %d\n", i, va, vb);
10012
10013 if (va < vb)
10014 return -1;
10015 else if (va > vb)
10016 return 1;
10017
10018 // values are equal, skip the the end of the digits, compare any trailing text
10019 continue;
10020 }
10021
10022 if (sa[i]==sb[i]) {
10023 continue;
10024 }
10025
10026 if (debug)
10027 printf("index %d, char [%c] [%c]\n", i, sa[i], sb[i]);
10028
10029 if (sa[i] == 0) // string sa is shorter
10030 return -1;
10031 else if (sb[i] == 0) // string sb is shorter
10032 return 1;
10033
10034 if (sa[i]<sb[i])
10035 return -1;
10036 else
10037 return 1;
10038 }
10039
10040 // NOT REACHED
10041}
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 10053 of file mhttpd.cxx.

10054{
10055 return cmp_names(a.name, b.name) < 0;
10056}
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 10111 of file mhttpd.cxx.

10112{
10113 return a.order < b.order;
10114}
Here is the caller graph for this function:

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13469 of file mhttpd.cxx.

13470{
13471 _abort = true;
13472}
std::atomic_bool _abort
Definition mhttpd.cxx:13467
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14223 of file mhttpd.cxx.

14224{
14225 // extract password cookies
14226
14227 char cookie_pwd[256]; // general access password
14228 char cookie_wpwd[256]; // "write mode" password
14229 char cookie_cpwd[256]; // custom page and javascript password
14230
14231 cookie_pwd[0] = 0;
14232 cookie_wpwd[0] = 0;
14233 cookie_cpwd[0] = 0;
14234
14235 std::string s = find_cookie_mg(msg, "midas_pwd");
14236 if (s.length() > 0) {
14237 mstrlcpy(cookie_pwd, s.c_str(), sizeof(cookie_pwd));
14238 cookie_pwd[strcspn(cookie_pwd, " ;\r\n")] = 0;
14239 }
14240
14241 s = find_cookie_mg(msg, "midas_wpwd");
14242 if (s.length()) {
14243 mstrlcpy(cookie_wpwd, s.c_str(), sizeof(cookie_pwd));
14244 cookie_wpwd[strcspn(cookie_wpwd, " ;\r\n")] = 0;
14245 }
14246
14247 s = find_cookie_mg(msg, "cpwd");
14248 if (s.length()) {
14249 mstrlcpy(cookie_cpwd, s.c_str(), sizeof(cookie_pwd));
14250 cookie_cpwd[strcspn(cookie_cpwd, " ;\r\n")] = 0;
14251 }
14252
14253 // extract refresh rate
14254 c->refresh = DEFAULT_REFRESH;
14255 s = find_cookie_mg(msg, "midas_refr");
14256 if (s.length() > 0)
14257 c->refresh = atoi(s.c_str());
14258
14259 // extract equipment expand flag
14260 //c->expand_equipment = 0;
14261 //s = find_cookie_mg(msg, "midas_expeq");
14262 //if (s.length() > 0)
14263 // c->expand_equipment = atoi(s.c_str());
14264
14265 c->cookie_pwd = cookie_pwd;
14266 c->cookie_wpwd = cookie_wpwd;
14267 c->cookie_cpwd = cookie_cpwd;
14268}
#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:14171
char c
Definition system.cxx:1312
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 13211 of file mhttpd.cxx.

13212{
13213 char path[256];
13214
13215 //printf("decode_get: string [%s], decode_url %d, url [%s], query_string [%s]\n", string, decode_url, url, query_string);
13216
13217 Param* param = new Param();
13218
13219 param->initparam();
13220
13221 if (url)
13222 mstrlcpy(path, url + 1, sizeof(path)); /* strip leading '/' */
13223 else {
13224 mstrlcpy(path, string + 1, sizeof(path)); /* strip leading '/' */
13225
13226 if (strchr(path, '?'))
13227 *strchr(path, '?') = 0;
13228 }
13229
13230 param->setparam("path", path);
13231
13232 assert(query_string != NULL);
13233
13234 decode_query(param, query_string);
13235
13236 param->setparam("query", query_string);
13237
13238 char dec_path[256];
13239 mstrlcpy(dec_path, path, sizeof(dec_path));
13240
13241 interprete(param, rr, NULL, c, dec_path, t);
13242
13243 param->freeparam();
13244 delete param;
13245}
char param[10][256]
Definition mana.cxx:250
void decode_query(Param *pp, const char *query_string)
Definition mhttpd.cxx:13186
void interprete(Param *p, Return *r, Attachment *a, const Cookies *c, const char *dec_path, RequestTrace *t)
Definition mhttpd.cxx:12267
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 13249 of file mhttpd.cxx.

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

13187{
13188 int len = strlen(query_string);
13189 char *buf = (char *)malloc(len+1);
13190 assert(buf != NULL);
13191 memcpy(buf, query_string, len+1);
13192 char* p = buf;
13193 p = strtok(p, "&");
13194 while (p != NULL) {
13195 char *pitem = p;
13196 p = strchr(p, '=');
13197 if (p != NULL) {
13198 *p++ = 0;
13199 urlDecode(pitem); // parameter name
13200 if (!equal_ustring(pitem, "format"))
13201 urlDecode(p); // parameter value
13202
13203 pp->setparam(pitem, p); // decoded query parameters
13204
13205 p = strtok(NULL, "&");
13206 }
13207 }
13208 free(buf);
13209}
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3206
static void urlDecode(char *p)
Definition mhttpd.cxx:882
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 10491 of file mhttpd.cxx.

10492{
10493 /* delete variables according to "hist_order" */
10494
10495 while (1) {
10496 bool something_deleted = false;
10497 for (unsigned i=0; i<hp.vars.size(); i++) {
10498 if (hp.vars[i].order <= 0) {
10499 hp.vars.erase(hp.vars.begin() + i);
10500 something_deleted = true;
10501 }
10502 }
10503 if (!something_deleted)
10504 break;
10505 }
10506}
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 4325 of file mhttpd.cxx.

4326{
4327 int status;
4328
4329 const char *name = p->getparam("name");
4330 const char *cmd = p->getparam("rcmd");
4331 const char *args = p->getparam("rarg");
4332
4333 if (!name || !cmd || !args) {
4335 r->rsprintf("<INVALID_ARGUMENTS>");
4336 return;
4337 }
4338
4340
4341 int buf_length = 1024;
4342
4343 int max_reply_length = atoi(p->getparam("max_reply_length"));
4346
4347 char* buf = (char*)malloc(buf_length);
4348 assert(buf != NULL);
4349
4350 buf[0] = 0;
4351
4352 HNDLE hconn;
4353
4355
4356 if (status != RPC_SUCCESS) {
4357 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4358 free(buf);
4359 return;
4360 }
4361
4363
4364 if (status != RPC_SUCCESS) {
4365 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4366 free(buf);
4367 return;
4368 }
4369
4370 r->rsprintf("%s", buf);
4371
4372 //status = cm_disconnect_client(hconn, FALSE);
4373
4374 free(buf);
4375}
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2780
#define RPC_SUCCESS
Definition midas.h:698
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13494
#define RPC_JRPC
Definition mrpc.h:130
void show_text_header(Return *r)
Definition mhttpd.cxx:1829
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 4019 of file mhttpd.cxx.

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

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

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

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

14172{
14173 const std::string cookies = find_header_mg(msg, "Cookie");
14174 if (cookies.length() < 1)
14175 return "";
14176 const char* p = strstr(cookies.c_str(), cookie_name);
14177 if (!p)
14178 return "";
14179 const char* v = p+strlen(cookie_name);
14180 if (*v != '=')
14181 return "";
14182 v++;
14183 //printf("cookie [%s] value [%s]\n", cookie_name, v);
14184 return v;
14185}
static const std::string find_header_mg(const struct http_message *msg, const char *name)
Definition mhttpd.cxx:14158
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 13688 of file mhttpd.cxx.

13689{
13690 std::string exptdir = cm_get_path();
13691
13692 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13693 return SUCCESS;
13694
13695 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13696 return SUCCESS;
13697
13698 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13699 return SUCCESS;
13700
13701 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13702 return SUCCESS;
13703
13704 // setup default filename
13705 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13706 return SS_FILE_ERROR;
13707}
std::string cm_get_path()
Definition midas.cxx:1551
#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:13655
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 14158 of file mhttpd.cxx.

14159{
14160 size_t nlen = strlen(name);
14161 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14162 if (msg->header_names[i].len != nlen)
14163 continue;
14164 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14165 continue;
14166 return mgstr(&msg->header_values[i]);
14167 }
14168 return "";
14169}
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:14153
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 3096 of file mhttpd.cxx.

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

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

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

1136{
1137 std::string ext_upper;
1138 const char* p = filename;
1139 const char* last_dot = NULL;
1140 for (; *p; p++) {
1141 if (*p == '.')
1142 last_dot = p;
1143 if (*p == DIR_SEPARATOR)
1144 last_dot = NULL;
1145 }
1146
1147 if (last_dot) {
1148 p = last_dot;
1149 for (; *p; p++)
1150 ext_upper += toupper(*p);
1151 }
1152
1153 //printf("filename: [%s], ext [%s]\n", filename, ext_upper.c_str());
1154
1155 std::string type = GetMimetype(ext_upper);
1156 if (type.length() > 0)
1157 return type;
1158
1159 cm_msg(MERROR, "get_content_type", "Unknown HTTP Content-Type for resource file \'%s\', file extension \'%s\'", filename, ext_upper.c_str());
1160
1161 return "text/plain";
1162}
static std::string GetMimetype(const std::string &ext)
Definition mhttpd.cxx:181
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 8531 of file mhttpd.cxx.

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

8168{
8169 int status;
8170 HNDLE hDB;
8171
8172 // history reconnect requested by watch callback?
8173
8174 if (gDoReloadHistory) {
8175 gDoReloadHistory = false;
8176 reset = true;
8177 }
8178
8179 // disconnect from previous history
8180
8181 if (reset && gMh) {
8182 gMh->hs_disconnect();
8183 delete gMh;
8184 gMh = NULL;
8185 gMhkey = 0;
8186 }
8187
8189 assert(status == CM_SUCCESS);
8190
8191 // setup a watch on history configuration
8192
8194 HNDLE hKey;
8195 gDoSetupHistoryWatch = false;
8196
8197 status = db_find_key(hDB, 0, "/Logger/History", &hKey);
8198 if (status == DB_SUCCESS)
8200
8201 status = db_find_key(hDB, 0, "/History/LoggerHistoryChannel", &hKey);
8202 if (status == DB_SUCCESS)
8204 }
8205
8206 // find out if ODB settings have changed and we need to connect to a different history channel
8207
8208 HNDLE hKey = 0;
8210 if (status != HS_SUCCESS)
8211 return gMh;
8212
8213 //printf("mh %p, hKey %d, mhkey %d\n", mh, hKey, mhkey);
8214
8215 if (gMh && hKey == gMhkey) // same channel as before
8216 return gMh;
8217
8218 if (gMh) {
8219 delete gMh;
8220 gMh = NULL;
8221 gMhkey = 0;
8222 }
8223
8225 if (status != HS_SUCCESS || gMh==NULL) {
8226 cm_msg(MERROR, "get_history", "Cannot configure history, hs_get_history() status %d", status);
8227 gMh = NULL;
8228 return NULL;
8229 }
8230
8231 gMhkey = hKey;
8232
8233 // cm_msg(MINFO, "get_history", "Reading history from channel \'%s\' type \'%s\'", mh->name, mh->type);
8234
8235 return gMh;
8236}
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:13823
#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:8155
static HNDLE gMhkey
Definition mhttpd.cxx:8163
static bool gDoReloadHistory
Definition mhttpd.cxx:8153
static MidasHistoryInterface * gMh
Definition mhttpd.cxx:8162
static bool gDoSetupHistoryWatch
Definition mhttpd.cxx:8152
static BOOL verbose
Definition mhttpd.cxx:96
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 16200 of file mhttpd.cxx.

16201{
16202 if (!params) {
16203 MJSO *doc = MJSO::I();
16204 doc->D("get current value of mhttpd http_trace");
16205 doc->P(NULL, 0, "there are no input parameters");
16206 doc->R(NULL, MJSON_INT, "current value of http_trace");
16207 return doc;
16208 }
16209
16210 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16211}
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
static int http_trace
Definition mhttpd.cxx:435
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 991 of file mhttpd.cxx.

992{
993 HNDLE hDB;
994 int status;
995
997
998 std::vector<std::string> paths;
999
1000 // add /Experiment/Resources
1001 std::string buf;
1002 status = db_get_value_string(hDB, 0, "/Experiment/Resources", 0, &buf, TRUE);
1003 if (status == DB_SUCCESS && buf.length() > 0)
1004 paths.push_back(buf);
1005
1006 // add "/Logger/History/IMAGE/History dir"
1007 paths.push_back(cm_get_history_path("IMAGE"));
1008
1009 // add /Logger/Data dir
1010 status = db_get_value_string(hDB, 0, "/Logger/Data dir", 0, &buf, TRUE);
1011 if (status == DB_SUCCESS && buf.length() > 0)
1012 paths.push_back(buf);
1013
1014 std::string cwd = ss_getcwd();
1015 if (!cwd.empty()) {
1016 paths.push_back(cwd + "/");
1017 paths.push_back(cwd + "/resources/");
1018 }
1019 paths.push_back(cm_get_path());
1020 paths.push_back(cm_get_path() + "resources/");
1021 char *m = getenv("MIDASSYS");
1022 if (m) {
1023 paths.push_back(std::string(m) + "/resources/");
1024 }
1025
1026 return paths;
1027}
std::string cm_get_history_path(const char *history_channel)
Definition midas.cxx:5865
std::string ss_getcwd()
Definition system.cxx:5848
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 181 of file mhttpd.cxx.

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

◆ GetTimeSec()

static double GetTimeSec ( )
static

Definition at line 376 of file mhttpd.cxx.

377{
378 struct timeval tv;
380 return tv.tv_sec*1.0 + tv.tv_usec/1000000.0;
381}
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 14274 of file mhttpd.cxx.

14275{
14277
14278 decode_cookies(&cookies, msg);
14279
14280 // lock shared structures
14281
14282#ifdef HAVE_MONGOOSE6
14284 assert(status == SS_SUCCESS);
14285#endif
14286
14287 //t->fTimeLocked = GetTimeSec();
14288
14289 // prepare return buffer
14290
14291 Return *rr = new Return();
14292
14293 rr->zero();
14294
14295 // call midas
14296
14297 decode_get(rr, NULL, &cookies, uri, query_string, t);
14298
14299 if (trace_mg)
14300 printf("handle_decode_get: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14301
14303
14304 if (rr->return_length == -1) {
14305 delete rr;
14306#ifdef HAVE_MONGOOSE6
14307 //t->fTimeUnlocked = GetTimeSec();
14309#endif
14310 return RESPONSE_501;
14311 }
14312
14313 if (rr->return_length == 0)
14314 rr->return_length = strlen(rr->return_buffer);
14315
14316 //t->fTimeUnlocked = GetTimeSec();
14317
14318#ifdef HAVE_MONGOOSE6
14320#endif
14321
14322 mg_send(nc, rr->return_buffer, rr->return_length);
14323
14324 if (!strstr(rr->return_buffer, "Content-Length")) {
14325 // cannot do pipelined http if response generated by mhttpd
14326 // decode_get() has no Content-Length header.
14327 // must close the connection.
14329 }
14330
14331 t->fTimeSent = GetTimeSec();
14332
14333 delete rr;
14334
14335 return RESPONSE_SENT;
14336}
double fTimeSent
Definition mhttpd.cxx:392
double fTimeProcessed
Definition mhttpd.cxx:391
#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:3229
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
Definition system.cxx:3109
static bool trace_mg
Definition mhttpd.cxx:13721
#define RESPONSE_501
Definition mhttpd.cxx:14272
void decode_cookies(Cookies *c, const http_message *msg)
Definition mhttpd.cxx:14223
void decode_get(Return *rr, char *string, const Cookies *c, const char *url, const char *query_string, RequestTrace *t)
Definition mhttpd.cxx:13211
#define RESPONSE_SENT
Definition mhttpd.cxx:14270
static double GetTimeSec()
Definition mhttpd.cxx:376
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 14744 of file mhttpd.cxx.

14745{
14746
14747 char boundary[256];
14748 boundary[0] = 0;
14749 const std::string ct = find_header_mg(msg, "Content-Type");
14750 if (ct.length() > 0) {
14751 const char* s = strstr(ct.c_str(), "boundary=");
14752 if (s)
14753 mstrlcpy(boundary, s+9, sizeof(boundary));
14754 }
14755
14756#ifdef HAVE_MONGOOSE616
14757 if (multithread_mg)
14758 return queue_decode_post(nc, msg, boundary, uri, query_string, t);
14759#endif
14760
14762
14763 decode_cookies(&cookies, msg);
14764
14765 const char* post_data = msg->body.p;
14766 int post_data_len = msg->body.len;
14767
14768 // lock shared strctures
14769
14770#ifdef HAVE_MONGOOSE6
14772 assert(status == SS_SUCCESS);
14773#endif
14774
14775 // prepare return buffer
14776
14777 Return* rr = new Return;
14778
14779 rr->zero();
14780
14781 //printf("post_data_len %d, data [%s], boundary [%s]\n", post_data_len, post_data, boundary);
14782
14783 decode_post(rr, NULL, (char*)post_data, boundary, post_data_len, &cookies, uri, t);
14784
14785 if (trace_mg)
14786 printf("handle_decode_post: return buffer length %d bytes, strlen %d\n", rr->return_length, (int)strlen(rr->return_buffer));
14787
14788 if (rr->return_length == -1) {
14789#ifdef HAVE_MONGOOSE6
14791#endif
14792 delete rr;
14793 return RESPONSE_501;
14794 }
14795
14796 if (rr->return_length == 0)
14797 rr->return_length = strlen(rr->return_buffer);
14798
14799#ifdef HAVE_MONGOOSE6
14801#endif
14802
14803 mg_send(nc, rr->return_buffer, rr->return_length);
14804
14805 if (!strstr(rr->return_buffer, "Content-Length")) {
14806 // cannot do pipelined http if response generated by mhttpd
14807 // decode_get() has no Content-Length header.
14808 // must close the connection.
14810 }
14811
14812 delete rr;
14813
14814 return RESPONSE_SENT;
14815}
void zero()
Definition mhttpd.cxx:549
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:13249
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 14189 of file mhttpd.cxx.

14190{
14191 struct mbuf *io = &nc->recv_mbuf;
14192 switch (ev) {
14193 case MG_EV_POLL: // periodic call from loop_mg() via mg_mgr_poll()
14194 break;
14195 case MG_EV_ACCEPT:
14196 if (trace_mg)
14197 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> accept\n", nc, ev, ev_data);
14198 break;
14199 case MG_EV_RECV:
14200 if (trace_mg)
14201 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);
14202#if 0
14203 // This event handler implements simple TCP echo server
14204 mg_send(nc, io->buf, io->len); // Echo received data back
14205 mbuf_remove(io, io->len); // Discard data from recv buffer
14206#endif
14207 break;
14208 case MG_EV_SEND:
14209 if (trace_mg)
14210 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> send %d bytes\n", nc, ev, ev_data, *(int*)ev_data);
14211 break;
14212 case MG_EV_CLOSE:
14213 if (trace_mg)
14214 printf("handle_event_mg: nc %p, ev %d, ev_data %p -> close\n", nc, ev, ev_data);
14215 break;
14216 default:
14217 if (trace_mg)
14218 printf("handle_event_mg: nc %p, ev %d, ev_data %p\n", nc, ev, ev_data);
14219 break;
14220 }
14221}
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 14817 of file mhttpd.cxx.

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

15097{
15098 std::string method = mgstr(&msg->method);
15099 std::string query_string = mgstr(&msg->query_string);
15100 std::string uri_encoded = mgstr(&msg->uri);
15101 std::string uri = UrlDecode(uri_encoded.c_str());
15102
15103 if (trace_mg)
15104 printf("handle_http_message: method [%s] uri [%s] proto [%s]\n", method.c_str(), uri.c_str(), mgstr(&msg->proto).c_str());
15105
15106 RequestTrace* t = new RequestTrace;
15108 t->fMethod = method;
15109 t->fUri = uri;
15110 t->fQuery = query_string;
15111
15112 // process OPTIONS for Cross-origin (CORS) preflight request
15113 // see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
15114 if (method == "OPTIONS" && query_string == "mjsonrpc" && mg_get_http_header(msg, "Access-Control-Request-Method") != NULL) {
15115 handle_http_options_cors(nc, msg, t);
15116 t->fCompleted = true;
15118 return;
15119 }
15120
15122 std::string username = check_digest_auth(msg, gAuthMg);
15123
15124 // Cannot re-read the password file - it is not thread safe to do so
15125 // unless I lock gAuthMg for each call check_digest_auth() and if I do so,
15126 // I will serialize (single-thread) all the http requests and defeat
15127 // the whole point of multithreading the web server. K.O.
15128 //
15130 //if (username.length() < 1) {
15131 // bool ok = read_passwords(&gAuthMg);
15132 // if (ok)
15133 // username = check_digest_auth(msg, &gAuthMg);
15134 //}
15135
15136 if (trace_mg)
15137 printf("handle_http_message: auth user: \"%s\"\n", username.c_str());
15138
15139 if (username.length() == 0) {
15140 if (trace_mg||verbose_mg)
15141 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());
15142
15144 t->fCompleted = true;
15146 return;
15147 }
15148 t->fAuthOk = true;
15149 } else {
15150 t->fAuthOk = true;
15151 }
15152
15153#ifdef HAVE_MONGOOSE616
15154 if (gProxyOdb && starts_with(uri, "/proxy/")) {
15155 std::string::size_type p1 = uri.find("/", 1);
15156 if (p1 == uri.length()-1) {
15157 std::string response = "404 Not Found (Proxy name is missing)";
15158 mg_send_head(nc, 404, response.length(), NULL);
15159 mg_send(nc, response.c_str(), response.length());
15160 delete t;
15161 return;
15162 }
15163 std::string::size_type p2 = uri.find("/", p1+1);
15164 if (p2 == std::string::npos) {
15165 std::string response = "404 Not Found (Proxy URL should end with a slash)";
15166 mg_send_head(nc, 404, response.length(), NULL);
15167 mg_send(nc, response.c_str(), response.length());
15168 delete t;
15169 return;
15170 }
15171 std::string p = uri.substr(p1+1, p2-p1-1);
15172 //printf("uri [%s], p1: %d, p2: %d, substr: [%s]\n", uri.c_str(), (int)p1, (int)p2, p.c_str());
15173 if (p.length() < 1) {
15174 std::string response = "404 Not Found (Double-slash or Proxy name is too short)";
15175 mg_send_head(nc, 404, response.length(), NULL);
15176 mg_send(nc, response.c_str(), response.length());
15177 delete t;
15178 return;
15179 }
15180 std::string destination;
15181 gProxyOdb->RS(p.c_str(), &destination);
15182 if (destination.length() < 1) {
15183 std::string response = "404 Not Found (Proxy not found in ODB)";
15184 mg_send_head(nc, 404, response.length(), NULL);
15185 mg_send(nc, response.c_str(), response.length());
15186 delete t;
15187 return;
15188 } else if (destination[0] == '#') {
15189 std::string response = "404 Not Found (Proxy commented-out in ODB)";
15190 mg_send_head(nc, 404, response.length(), NULL);
15191 mg_send(nc, response.c_str(), response.length());
15192 delete t;
15193 return;
15194 } else if (ends_with_char(destination, '/')) {
15195 std::string response = "404 Not Found (Proxy address should not end with a slash)";
15196 mg_send_head(nc, 404, response.length(), NULL);
15197 mg_send(nc, response.c_str(), response.length());
15198 delete t;
15199 return;
15200 } else if (!starts_with(destination, "http")) {
15201 std::string response = "404 Not Found (Proxy address does not start with http";
15202 mg_send_head(nc, 404, response.length(), NULL);
15203 mg_send(nc, response.c_str(), response.length());
15204 delete t;
15205 return;
15206 } else {
15207 std::string m;
15208 m += "/proxy";
15209 m += "/";
15210 m += p;
15211 mg_str mount = mg_mk_str(m.c_str());
15213 if (verbose_mg||trace_mg) {
15214 printf("proxy: uri [%s] mount [%s] upstream [%s]\n", uri.c_str(), mgstr(&mount).c_str(), mgstr(&upstream).c_str());
15215 }
15217 delete t;
15218 return;
15219 }
15220 }
15221#endif
15222
15223 int response = RESPONSE_501;
15224
15225 if (method == "GET")
15226 response = handle_http_get(nc, msg, uri.c_str(), t);
15227 else if (method == "POST")
15228 response = handle_http_post(nc, msg, uri.c_str(), t);
15229
15230 if (response == RESPONSE_501) {
15231 if (trace_mg||verbose_mg)
15232 printf("handle_http_message: sending 501 Not Implemented error\n");
15233
15234 std::string response = "501 Not Implemented";
15235 mg_send_head(nc, 501, response.length(), NULL); // 501 Not Implemented
15236 mg_send(nc, response.c_str(), response.length());
15237 }
15238
15239 if (response != RESPONSE_QUEUED) {
15240 t->fCompleted = true;
15242 }
15243}
std::string realm
Definition mhttpd.cxx:13741
void AddTraceMTS(RequestTrace *t)
Definition mhttpd.cxx:463
std::string fQuery
Definition mhttpd.cxx:396
std::string fMethod
Definition mhttpd.cxx:394
std::string fUri
Definition mhttpd.cxx:395
bool fCompleted
Definition mhttpd.cxx:393
double fTimeReceived
Definition mhttpd.cxx:388
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:14900
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:13909
static std::string UrlDecode(const char *p)
Definition mhttpd.cxx:843
bool starts_with(const std::string &s1, const char *s2)
Definition mhttpd.cxx:4438
#define RESPONSE_QUEUED
Definition mhttpd.cxx:14271
static int handle_http_get(struct mg_connection *nc, const http_message *msg, const char *uri, RequestTrace *t)
Definition mhttpd.cxx:14817
static RequestTraceBuf * gTraceBuf
Definition mhttpd.cxx:506
static void xmg_http_send_digest_auth_request(struct mg_connection *c, const char *domain)
Definition mhttpd.cxx:13803
static void handle_http_options_cors(struct mg_connection *nc, const http_message *msg, RequestTrace *t)
Definition mhttpd.cxx:15026
static Auth * gAuthMg
Definition mhttpd.cxx:13769
bool ends_with_char(const std::string &s, char c)
Definition midas.cxx:412
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 15026 of file mhttpd.cxx.

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

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

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

8156{
8157 //printf("history_watch_callback %d %d %d\n", hDB, hKey, index);
8158 gDoReloadHistory = true;
8159 cm_msg(MINFO, "history_watch_callback", "History configuration may have changed, will reconnect");
8160}
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 1981 of file mhttpd.cxx.

1982{
1983 HNDLE hDB;
1984 int size;
1985 HNDLE hkey;
1987
1989 std::string external_elog_url;
1990
1991 size = sizeof(external_elog);
1992 db_get_value(hDB, 0, "/Elog/External Elog", &external_elog, &size, TID_BOOL, TRUE);
1993 db_get_value_string(hDB, 0, "/Elog/URL", 0, &external_elog_url, TRUE);
1994
1997 size = sizeof(BOOL);
1998 db_get_value(hDB, 0, "/Elog/Allow delete", &allow_delete, &size, TID_BOOL, TRUE);
1999 db_get_value(hDB, 0, "/Elog/Allow edit", &allow_edit, &size, TID_BOOL, TRUE);
2000 //db_get_value(hDB, 0, "/Elog/Display run number", &display_run_number, &size, TID_BOOL, TRUE);
2001
2002 if (db_find_key(hDB, 0, "/Elog/Buttons", &hkey) != DB_SUCCESS) {
2003 const char def_button[][NAME_LENGTH] = { "8h", "24h", "7d" };
2004 db_set_value(hDB, 0, "/Elog/Buttons", def_button, NAME_LENGTH*3, 3, TID_STRING);
2005 }
2006
2007
2008 /* get type list from ODB */
2009 size = 20 * NAME_LENGTH;
2010 if (db_find_key(hDB, 0, "/Elog/Types", &hkey) != DB_SUCCESS) {
2011 db_set_value(hDB, 0, "/Elog/Types", default_type_list, NAME_LENGTH * 20, 20, TID_STRING);
2012 }
2013
2014 /* get system list from ODB */
2015 size = 20 * NAME_LENGTH;
2016 if (db_find_key(hDB, 0, "/Elog/Systems", &hkey) != DB_SUCCESS)
2017 db_set_value(hDB, 0, "/Elog/Systems", default_system_list, NAME_LENGTH * 20, 20, TID_STRING);
2018}
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:5266
static const char default_type_list[20][NAME_LENGTH]
Definition mhttpd.cxx:101
static const char default_system_list[20][NAME_LENGTH]
Definition mhttpd.cxx:116
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 1892 of file mhttpd.cxx.

1893{
1894 HNDLE hDB;
1897 int size = sizeof(true_value);
1899 db_get_value(hDB, 0, "/Experiment/Menu/Status", &true_value, &size, TID_BOOL, TRUE);
1900 db_get_value(hDB, 0, "/Experiment/Menu/Start", &false_value, &size, TID_BOOL, TRUE);
1901 db_get_value(hDB, 0, "/Experiment/Menu/Transition", &true_value, &size, TID_BOOL, TRUE);
1902 db_get_value(hDB, 0, "/Experiment/Menu/ODB", &true_value, &size, TID_BOOL, TRUE);
1903 db_get_value(hDB, 0, "/Experiment/Menu/OldODB", &true_value, &size, TID_BOOL, TRUE);
1904 db_get_value(hDB, 0, "/Experiment/Menu/Messages", &true_value, &size, TID_BOOL, TRUE);
1905 db_get_value(hDB, 0, "/Experiment/Menu/Chat", &true_value, &size, TID_BOOL, TRUE);
1906 db_get_value(hDB, 0, "/Experiment/Menu/Elog", &true_value, &size, TID_BOOL, TRUE);
1907 db_get_value(hDB, 0, "/Experiment/Menu/Alarms", &true_value, &size, TID_BOOL, TRUE);
1908 db_get_value(hDB, 0, "/Experiment/Menu/Programs", &true_value, &size, TID_BOOL, TRUE);
1909 db_get_value(hDB, 0, "/Experiment/Menu/Buffers", &true_value, &size, TID_BOOL, TRUE);
1910 db_get_value(hDB, 0, "/Experiment/Menu/History", &true_value, &size, TID_BOOL, TRUE);
1911 db_get_value(hDB, 0, "/Experiment/Menu/OldHistory", &true_value, &size, TID_BOOL, TRUE);
1912 db_get_value(hDB, 0, "/Experiment/Menu/MSCB", &true_value, &size, TID_BOOL, TRUE);
1913 db_get_value(hDB, 0, "/Experiment/Menu/Sequencer", &true_value, &size, TID_BOOL, TRUE);
1914 db_get_value(hDB, 0, "/Experiment/Menu/PySequencer",&true_value, &size, TID_BOOL, TRUE);
1915 db_get_value(hDB, 0, "/Experiment/Menu/Event Dump", &true_value, &size, TID_BOOL, TRUE);
1916 db_get_value(hDB, 0, "/Experiment/Menu/Config", &true_value, &size, TID_BOOL, TRUE);
1917 db_get_value(hDB, 0, "/Experiment/Menu/Example", &false_value, &size, TID_BOOL, TRUE);
1918 db_get_value(hDB, 0, "/Experiment/Menu/Help", &true_value, &size, TID_BOOL, TRUE);
1919
1920 //std::string buf;
1921 //status = db_get_value_string(hDB, 0, "/Experiment/Menu buttons", 0, &buf, FALSE);
1922 //if (status == DB_SUCCESS) {
1923 // cm_msg(MERROR, "init_menu_buttons", "ODB \"/Experiment/Menu buttons\" is obsolete, please delete it.");
1924 //}
1925
1926 check_obsolete_odb(hDB, "/Experiment/Menu buttons");
1927 check_obsolete_odb(hDB, "/Experiment/Menu/OldSequencer");
1928 check_obsolete_odb(hDB, "/Experiment/Menu/NewSequencer");
1929}
void check_obsolete_odb(HNDLE hDB, const char *odb_path)
Definition mhttpd.cxx:1883
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 1933 of file mhttpd.cxx.

1934{
1935 HNDLE hDB;
1936 HNDLE hKey;
1937 int status;
1938 std::string s;
1940
1941 status = db_find_key(hDB, 0, "/Experiment/Base URL", &hKey);
1942 if (status == DB_SUCCESS) {
1943 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Base URL\" is obsolete, please delete it.");
1944 }
1945
1946 status = db_find_key(hDB, 0, "/Experiment/CSS File", &hKey);
1947 if (status == DB_SUCCESS) {
1948 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/CSS File\" is obsolete, please delete it.");
1949 }
1950
1951 status = db_find_key(hDB, 0, "/Experiment/JS File", &hKey);
1952 if (status == DB_SUCCESS) {
1953 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/JS File\" is obsolete, please delete it.");
1954 }
1955
1956 status = db_find_key(hDB, 0, "/Experiment/Start-Stop Buttons", &hKey);
1957 if (status == DB_SUCCESS) {
1958 cm_msg(MERROR, "init_mhttpd_odb", "ODB \"/Experiment/Start-Stop Buttons\" is obsolete, please delete it.");
1959 }
1960
1961 bool xdefault = true;
1962 odb->RB("Experiment/Pause-Resume Buttons", &xdefault, true);
1963
1964#ifdef HAVE_MONGOOSE616
1965 check_obsolete_odb(hDB, "/Experiment/midas http port");
1966 check_obsolete_odb(hDB, "/Experiment/midas https port");
1967 check_obsolete_odb(hDB, "/Experiment/http redirect to https");
1968 check_obsolete_odb(hDB, "/Experiment/Security/mhttpd hosts");
1969#endif
1970
1971 status = db_find_key(hDB, 0, "/Logger/Message file", &hKey);
1972 if (status == DB_SUCCESS) {
1973 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.");
1974 }
1975
1976 check_obsolete_odb(hDB, "/Logger/Watchdog timeout");
1977}
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 12267 of file mhttpd.cxx.

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

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

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

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

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

◆ Lock()

void Lock ( RequestTrace t)

Definition at line 12253 of file mhttpd.cxx.

12254{
12255 gMutex.lock();
12256 t->fTimeLocked = GetTimeSec();
12257}
double fTimeLocked
Definition mhttpd.cxx:389
static std::mutex gMutex
Definition mhttpd.cxx:47
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 16235 of file mhttpd.cxx.

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

14154{
14155 return std::string(s->p, s->len);
14156}
Here is the caller graph for this function:

◆ mhttpd_revision()

const char * mhttpd_revision ( void  )

Definition at line 836 of file mhttpd.cxx.

837{
838 return cm_get_revision();
839}
const char * cm_get_revision()
Definition midas.cxx:1498
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 9755 of file mhttpd.cxx.

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

10127{
10128 const char* const colour[] =
10129 {
10130 "#00AAFF", "#FF9000", "#FF00A0", "#00C030",
10131 "#A0C0D0", "#D0A060", "#C04010", "#807060",
10132 "#F0C000", "#2090A0", "#D040D0", "#90B000",
10133 "#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0",
10134 NULL };
10135
10136 for (int i=0; colour[i]; i++) {
10137 bool in_use = false;
10138
10139 for (size_t j=0; j<hp.vars.size(); j++)
10140 if (hp.vars[j].colour == colour[i]) {
10141 in_use = true;
10142 break;
10143 }
10144
10145 if (!in_use)
10146 return colour[i];
10147 }
10148
10149 return "#808080";
10150}
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 10152 of file mhttpd.cxx.

10153{
10154 int order = 0;
10155 for (size_t i=0; i<hp.vars.size(); i++)
10156 if (hp.vars[i].order > order)
10157 order = hp.vars[i].order;
10158 return order + 10;
10159}
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 1031 of file mhttpd.cxx.

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

4380{
4381 int size, i;
4382 HNDLE hDB, hsubkey;
4383 KEY key;
4384 char data[TEXT_SIZE];
4385
4387
4388 db_get_key(hDB, hkey, &key);
4389 if (key.type == TID_KEY) {
4390 for (i=0 ; ; i++) {
4392 if (!hsubkey)
4393 break;
4394 output_key(p, r, hsubkey, -1, format);
4395 }
4396 } else {
4397 if (key.item_size <= (int)sizeof(data)) {
4398 size = sizeof(data);
4399 db_get_data(hDB, hkey, data, &size, key.type);
4400 if (index == -1) {
4401 for (i=0 ; i<key.num_values ; i++) {
4402 if (p->isparam("name") && atoi(p->getparam("name")) == 1) {
4403 if (key.num_values == 1)
4404 r->rsprintf("%s:", key.name);
4405 else
4406 r->rsprintf("%s[%d]:", key.name, i);
4407 }
4408 std::string data_str;
4409 if (format && format[0])
4411 else
4413 r->rsputs(data_str.c_str());
4414 if (i<key.num_values-1)
4415 r->rsputs("\n");
4416 }
4417 } else {
4418 if (p->isparam("name") && atoi(p->getparam("name")) == 1)
4419 r->rsprintf("%s[%d]:", key.name, index);
4420 if (index >= key.num_values)
4421 r->rsputs("<DB_OUT_OF_RANGE>");
4422 else {
4423 std::string data_str;
4424 if (p->isparam("format"))
4426 else
4428 r->rsputs(data_str.c_str());
4429 }
4430 }
4431 r->rsputs("\n");
4432 }
4433 }
4434}
INT db_sprintff(char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10925
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 10116 of file mhttpd.cxx.

10117{
10118 printf("hist plot: %d variables\n", (int)hp.vars.size());
10119 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);
10120
10121 for (size_t i=0; i<hp.vars.size(); i++) {
10122 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);
10123 }
10124}
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 8366 of file mhttpd.cxx.

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

13814{
13815 std::string path;
13816 FILE *fp;
13817 int status = find_file_mg("htpasswd.txt", path, &fp, trace_mg||verbose_mg);
13818
13819 auth->passwd_filename = path;
13820 auth->passwords.clear();
13821
13822 if (status != SUCCESS || fp == NULL) {
13823 cm_msg(MERROR, "mongoose", "mongoose web server cannot find password file \"%s\"", path.c_str());
13824 cm_msg(MERROR, "mongoose", "please create password file: touch %s", path.c_str());
13825 return false;
13826 }
13827
13828 bool have_realm = false;
13829 char buf[256];
13830
13831 /*
13832 * Read passwords file line by line. If should have htdigest format,
13833 * i.e. each line should be a colon-separated sequence:
13834 * USER_NAME:DOMAIN_NAME:HA1_HASH_OF_USER_DOMAIN_AND_PASSWORD
13835 */
13836 while (fgets(buf, sizeof(buf), fp) != NULL) {
13837 char f_user[256];
13838 char f_domain[256];
13839 char f_ha1[256];
13840
13841 if (sscanf(buf, "%[^:]:%[^:]:%s", f_user, f_domain, f_ha1) == 3) {
13842 AuthEntry e;
13843 e.realm = f_domain;
13844 e.username = f_user;
13845 e.password = f_ha1;
13846
13847 if (e.realm == auth->realm) {
13848 have_realm = true;
13849 auth->passwords.push_back(e);
13850 }
13851 }
13852 }
13853
13854 fclose(fp);
13855
13856 return have_realm;
13857}
int find_file_mg(const char *filename, std::string &path, FILE **fpp, bool trace)
Definition mhttpd.cxx:13688
std::string realm
Definition mhttpd.cxx:13735
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 1409 of file mhttpd.cxx.

1410{
1411 char str[256];
1412
1413 //printf("redirect to [%s]\n", path);
1414
1415 mstrlcpy(str, path, sizeof(str));
1416 if (str[0] == 0)
1417 strcpy(str, "./");
1418
1419 /* redirect */
1420 r->rsprintf("HTTP/1.1 302 Found\r\n");
1421 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1422 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1423
1424 if (strncmp(path, "http:", 5) == 0)
1425 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1426 else if (strncmp(path, "https:", 6) == 0)
1427 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1428 else {
1429 r->rsprintf("Location: %s\r\n\r\n<html>redir</html>\r\n", str);
1430 }
1431}
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 1446 of file mhttpd.cxx.

1447{
1448 redirect(r, path);
1449}
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 1433 of file mhttpd.cxx.

1434{
1435 //printf("redirect_307 to [%s]\n", path);
1436
1437 /* redirect */
1438 r->rsprintf("HTTP/1.1 307 Temporary Redirect\r\n");
1439 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1440 r->rsprintf("Content-Type: text/html; charset=%s\r\n", HTTP_ENCODING);
1441 r->rsprintf("Location: %s\r\n", path);
1442 r->rsprintf("\r\n");
1443 r->rsprintf("<html>redirect to %s</html>\r\n", path);
1444}
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 10415 of file mhttpd.cxx.

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

204{
205 gMimeTypesOdb = odb;
206
207 for (int i=0; gMimetypeTable[i].ext.length() > 0; i++) {
208 std::string tmp = gMimetypeTable[i].mimetype;
209 gMimeTypesOdb->RS(gMimetypeTable[i].ext.c_str(), &tmp, true);
210 }
211}
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 1459 of file mhttpd.cxx.

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

7761{
7762 char mon[80];
7763 time_t t_sec;
7764
7765 t_sec = (time_t) sec;
7766
7767 struct tm tms;
7768 localtime_r(&t_sec, &tms);
7769 strcpy(mon, mname[tms.tm_mon]);
7770 mon[3] = 0;
7771
7772 if (force_date) {
7773 if (base < 600)
7774 sprintf(result, "%02d %s %02d %02d:%02d:%02d",
7775 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min,
7776 tms.tm_sec);
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 } else {
7783 if (base < 600)
7784 sprintf(result, "%02d:%02d:%02d", tms.tm_hour, tms.tm_min, tms.tm_sec);
7785 else if (base < 3600 * 3)
7786 sprintf(result, "%02d:%02d", tms.tm_hour, tms.tm_min);
7787 else if (base < 3600 * 24)
7788 sprintf(result, "%02d %s %02d %02d:%02d",
7789 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7790 else
7791 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7792 }
7793}
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 1212 of file mhttpd.cxx.

1213{
1214 FILE *fp = fopen(path.c_str(), "rb");
1215
1216 if (!fp) {
1217 if (generate_404) {
1218 /* header */
1219 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1220 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1221 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1222 r->rsprintf("\r\n");
1223 r->rsprintf("Error: Cannot read \"%s\", fopen() errno %d (%s)\n", path.c_str(), errno, strerror(errno));
1224 }
1225 return false;
1226 }
1227
1228 return send_fp(r, path, fp);
1229}
bool send_fp(Return *r, const std::string &path, FILE *fp)
Definition mhttpd.cxx:1166
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 1166 of file mhttpd.cxx.

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

12202{
12203 int length;
12204 const unsigned char *picon;
12205 char str[256], format[256];
12206 time_t now;
12207
12208 if (strstr(icon, "favicon.ico") != 0) {
12209 length = sizeof(favicon_ico);
12211 } else if (strstr(icon, "favicon.png") != 0) {
12212 length = sizeof(favicon_png);
12214 } else
12215 return;
12216
12217 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
12218 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12219 r->rsprintf("Accept-Ranges: bytes\r\n");
12220
12221 /* set expiration time to one day */
12222 time(&now);
12223 now += (int) (3600 * 24);
12224 struct tm gmt_tms;
12225 gmtime_r(&now, &gmt_tms);
12226 strcpy(format, "%A, %d-%b-%y %H:%M:%S GMT");
12227 strftime(str, sizeof(str), format, &gmt_tms);
12228 r->rsprintf("Expires: %s\r\n", str);
12229
12230 if (equal_ustring(icon, "favicon.ico"))
12231 r->rsprintf("Content-Type: image/x-icon\r\n");
12232 else
12233 r->rsprintf("Content-Type: image/png\r\n");
12234
12235 r->rsprintf("Content-Length: %d\r\n\r\n", length);
12236
12237 r->rmemcpy(picon, length);
12238}
void rmemcpy(const void *buf, int len)
Definition mhttpd.cxx:578
const unsigned char favicon_png[]
Definition mhttpd.cxx:217
const unsigned char favicon_ico[]
Definition mhttpd.cxx:282
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 1231 of file mhttpd.cxx.

1232{
1233 std::string path;
1234 FILE *fp = NULL;
1235
1236 bool found = open_resource_file(name.c_str(), &path, &fp);
1237
1238 if (!found) {
1239 if (generate_404) {
1240 /* header */
1241 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1242 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1243 r->rsprintf("Content-Type: text/plain; charset=%s\r\n", HTTP_ENCODING);
1244 r->rsprintf("\r\n");
1245 r->rsprintf("Error: resource file \"%s\" not found, see messages\n", name.c_str());
1246 }
1247 return false;
1248 }
1249
1250 return send_fp(r, path, fp);
1251}
bool open_resource_file(const char *filename, std::string *ppath, FILE **pfp)
Definition mhttpd.cxx:1031
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 1255 of file mhttpd.cxx.

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

16214{
16215 if (!params) {
16216 MJSO* doc = MJSO::I();
16217 doc->D("set new value of mhttpd http_trace");
16218 doc->P(NULL, MJSON_INT, "new value of http_trace");
16219 doc->R(NULL, MJSON_INT, "new value of http_trace");
16220 return doc;
16221 }
16222
16223 http_trace = params->GetInt();
16224 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16225}
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 5664 of file mhttpd.cxx.

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

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

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

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

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

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

1842{
1843 /* header */
1844 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1845 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1846 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1847
1848 r->rsprintf("<html><head>\n");
1849 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1850 r->rsprintf("<title>MIDAS error</title></head>\n");
1851 r->rsprintf("<body><H1>%s</H1></body></html>\n", error);
1852}
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 1856 of file mhttpd.cxx.

1857{
1858 /* header */
1859 r->rsprintf("HTTP/1.1 404 Not Found\r\n");
1860 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1861 r->rsprintf("Content-Type: text/plain\r\n");
1862 r->rsprintf("\r\n");
1863
1864 r->rsprintf("MIDAS error: %s\n", error);
1865}
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 7577 of file mhttpd.cxx.

7578{
7579 HNDLE hDB, hkey;
7580
7582
7583 if (value[0] == 0) {
7584 /* without value, show find dialog */
7585 show_header(r, "Find value", "GET", "", 0);
7586
7587 //end header:
7588 r->rsprintf("</table>");
7589
7590 //find dialog:
7591 r->rsprintf("<table class=\"dialogTable\">");
7592
7593 r->rsprintf("<tr><th colspan=2>Find string in Online Database</tr>\n");
7594 r->rsprintf("<tr><td>Enter substring (case insensitive)\n");
7595
7596 r->rsprintf("<td><input type=\"text\" size=\"20\" maxlength=\"80\" name=\"value\">\n");
7597 r->rsprintf("</tr>");
7598
7599 r->rsprintf("<tr><td align=center colspan=2>");
7600 r->rsprintf("<input type=submit name=cmd value=Find>");
7601 r->rsprintf("<input type=submit name=cmd value=Cancel>");
7602 r->rsprintf("</tr>");
7603 r->rsprintf("</table>");
7604
7605 r->rsprintf("<input type=hidden name=cmd value=Find>");
7606
7607 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7608 r->rsprintf("</form>\n");
7609 r->rsprintf("</body></html>\r\n");
7610 } else {
7611 show_header(r, "Search results", "GET", "", 0);
7612
7613 r->rsprintf("<table class=\"mtable\">\n");
7614 r->rsprintf("<tr><th colspan=2 class=\"mtableheader\">");
7615 r->rsprintf("Results of search for substring \"%s\"</tr>\n", value);
7616 r->rsprintf("<tr><th class=\"titlerow\">Key<th>Value</tr>\n");
7617
7618 /* start from root */
7619 db_find_key(hDB, 0, "", &hkey);
7620 assert(hkey);
7621
7622 /* scan tree, call "search_callback" for each key */
7624 data.r = r;
7625 data.search_name = value;
7626
7627 db_scan_tree(hDB, hkey, 0, search_callback, (void *)&data);
7628
7629 r->rsprintf("</table>");
7630 r->rsprintf("</div>\n"); // closing for <div id="mmain">
7631 r->rsprintf("</form>\n");
7632 r->rsprintf("</body></html>\r\n");
7633 }
7634}
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
Definition odb.cxx:4772
INT search_callback(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
Definition mhttpd.cxx:1459
Return * r
Definition mhttpd.cxx:1455
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 1781 of file mhttpd.cxx.

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

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

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

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

1870{
1871 r->rsprintf("<script>\n");
1872 r->rsprintf("window.addEventListener(\"load\", function(e) { mhttpd_init('%s', 1000); });\n", cur_page);
1873 r->rsprintf("</script>\n");
1874
1875 r->rsprintf("<!-- header and side navigation will be filled in mhttpd_init -->\n");
1876 r->rsprintf("<div id=\"mheader\"></div>\n");
1877 r->rsprintf("<div id=\"msidenav\"></div>\n");
1878 r->rsprintf("<div id=\"mmain\">\n");
1879}
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 6803 of file mhttpd.cxx.

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

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

6713{
6714 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
6715 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
6716 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
6717
6718 r->rsprintf("<html><head>\n");
6719 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
6720 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
6721 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
6722 r->rsprintf("<title>Enter password</title></head><body>\n\n");
6723
6724 r->rsprintf("<form method=\"GET\" action=\".\">\n\n");
6725
6726 /*---- page header ----*/
6727 r->rsprintf("<table class=\"headerTable\"><tr><td></td><tr></table>\n");
6728
6729 r->rsprintf("<table class=\"dialogTable\">\n"); //main table
6730 if (password[0])
6731 r->rsprintf("<tr><th class=\"redLight\">Wrong password!</tr>\n");
6732
6733 r->rsprintf("<tr><th>Please enter password</tr>\n");
6734 r->rsprintf("<tr><td align=center><input type=password name=pwd></tr>\n");
6735 r->rsprintf("<tr><td align=center><input type=submit value=Submit></tr>");
6736
6737 r->rsprintf("</table>\n");
6738
6739 r->rsprintf("</div>\n"); // closing for <div id="mmain">
6740 r->rsprintf("</form>\n");
6741 r->rsprintf("</body></html>\r\n");
6742}
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 9801 of file mhttpd.cxx.

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

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

1830{
1831 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1832 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1833 r->rsprintf("Access-Control-Allow-Origin: *\r\n");
1834 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1835 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1836 r->rsprintf("Content-Type: text/plain; charset=%s\r\n\r\n", HTTP_ENCODING);
1837}
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 10508 of file mhttpd.cxx.

10509{
10510 /* sort variables according to "hist_order" */
10511
10512 bool need_sort = false;
10513 for (size_t i=1; i<hp.vars.size(); i++) {
10514 if (hp.vars[i-1].order >= hp.vars[i].order) {
10515 need_sort = true;
10516 }
10517 }
10518
10519 if (need_sort) {
10520 /* sort variables by order */
10521 std::sort(hp.vars.begin(), hp.vars.end(), cmp_vars);
10522
10523 /* renumber the variables according to the new sorted order */
10524 for (size_t index=0; index<hp.vars.size(); index++)
10525 hp.vars[index].order = (index+1)*10;
10526 }
10527}
static bool cmp_vars(const HistVar &a, const HistVar &b)
Definition mhttpd.cxx:10111
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 10161 of file mhttpd.cxx.

10161 {
10162 event_name = "";
10163 tag_name = "";
10164
10165 std::vector<size_t> colons;
10166
10167 for (size_t i = 0; i < var_name.size(); i++) {
10168 if (var_name[i] == ':') {
10169 colons.push_back(i);
10170 }
10171 }
10172
10173 if (colons.size() == 0) {
10174 // No colons - leave the tag name empty
10175 event_name = var_name;
10176 } else {
10177 size_t split_pos;
10178 size_t slash_pos = var_name.find("/");
10179 bool uses_per_variable_naming = (slash_pos != std::string::npos);
10180
10181 if (uses_per_variable_naming && colons.size() % 2 == 1) {
10182 size_t middle_colon_pos = colons[colons.size() / 2];
10183 std::string slash_to_mid = var_name.substr(slash_pos + 1, middle_colon_pos - slash_pos - 1);
10184 std::string mid_to_end = var_name.substr(middle_colon_pos + 1);
10185
10186 if (slash_to_mid == mid_to_end) {
10187 // Special case - we have a string of the form Beamlime/GS2:FC1:GS2:FC1.
10188 // Logger has already warned people that having colons in the equipment/event
10189 // names is a bad idea, so we only need to worry about them in the tag name.
10191 } else {
10192 // We have a string of the form Beamlime/Demand:GS2:FC1. Split at the first colon.
10193 split_pos = colons[0];
10194 }
10195 } else {
10196 // Normal case - split at the fist colon.
10197 split_pos = colons[0];
10198 }
10199
10200 event_name = var_name.substr(0, split_pos);
10201 tag_name = var_name.substr(split_pos + 1);
10202 }
10203}
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 4438 of file mhttpd.cxx.

4439{
4440 if (s1.length() < strlen(s2))
4441 return false;
4442 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4443}
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 2022 of file mhttpd.cxx.

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

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

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

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

◆ string_to_time()

time_t string_to_time ( const char str)

Definition at line 8127 of file mhttpd.cxx.

8128{
8129 time_t t = 0;
8130 for (; *str != 0; str++) {
8131 if (*str < '0')
8132 break;
8133 if (*str > '9')
8134 break;
8135 t *= 10;
8136 t += *str - '0';
8137 }
8138 return t;
8139}
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 341 of file mhttpd.cxx.

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

◆ submit_elog()

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

Definition at line 2251 of file mhttpd.cxx.

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

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

8103{
8104 double s;
8105
8106 s = atof(str);
8107 switch (str[strlen(str) - 1]) {
8108 case 'm':
8109 case 'M':
8110 s *= 60;
8111 break;
8112 case 'h':
8113 case 'H':
8114 s *= 3600;
8115 break;
8116 case 'd':
8117 case 'D':
8118 s *= 3600 * 24;
8119 break;
8120 }
8121
8122 return (int) s;
8123}
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 8143 of file mhttpd.cxx.

8144{
8145 char buf[256];
8146 sprintf(buf, "%.0f", (double)t);
8147 return buf;
8148}
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 57 of file mhttpd.cxx.

58{
59 char buf[256];
60 sprintf(buf, "%d", i);
61 return buf;
62}
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 13655 of file mhttpd.cxx.

13656{
13657 if (fpp)
13658 *fpp = NULL;
13659 if (!try_dir)
13660 return SS_FILE_ERROR;
13661 if (strlen(try_dir) < 1)
13662 return SS_FILE_ERROR;
13663
13664 path = try_dir;
13665 if (path[path.length()-1] != DIR_SEPARATOR)
13666 path += DIR_SEPARATOR_STR;
13667 path += filename;
13668
13669 FILE* fp = fopen(path.c_str(), "r");
13670
13671 if (trace) {
13672 if (fp)
13673 printf("file \"%s\": OK!\n", path.c_str());
13674 else
13675 printf("file \"%s\": not found.\n", path.c_str());
13676 }
13677
13678 if (!fp)
13679 return SS_FILE_ERROR;
13680 else if (fpp)
13681 *fpp = fp;
13682 else
13683 fclose(fp);
13684
13685 return SUCCESS;
13686}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12259 of file mhttpd.cxx.

12260{
12262 gMutex.unlock();
12263}
double fTimeUnlocked
Definition mhttpd.cxx:390
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 882 of file mhttpd.cxx.

886{
887 //char *px = p;
888 char *pD, str[3];
889 int i;
890
891 //printf("URL decode: [%s] --> ", p);
892
893 pD = p;
894 while (*p) {
895 if (*p == '%') {
896 /* Escape: next 2 chars are hex representation of the actual character */
897 p++;
898 if (isxdigit(p[0]) && isxdigit(p[1])) {
899 str[0] = p[0];
900 str[1] = p[1];
901 str[2] = 0;
902 sscanf(str, "%02X", &i);
903
904 *pD++ = (char) i;
905 p += 2;
906 } else
907 *pD++ = '%';
908 } else if (*p == '+') {
909 /* convert '+' to ' ' */
910 *pD++ = ' ';
911 p++;
912 } else {
913 *pD++ = *p++;
914 }
915 }
916 *pD = '\0';
917
918 //printf("[%s]\n", px);
919}
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 843 of file mhttpd.cxx.

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

926{
927 char *pd, *p;
928 int len = strlen(ps);
929 char *str = (char*)malloc(len*3 + 10); // at worst, each input character is expanded into 3 output characters
930
931 pd = str;
932 p = ps;
933 while (*p) {
934 if (isalnum(*p)) {
935 *pd++ = *p++;
936 } else {
937 sprintf(pd, "%%%02X", (*p)&0xFF);
938 pd += 3;
939 p++;
940 }
941 }
942 *pd = '\0';
943
944 if (/* DISABLES CODE */ (0)) {
945 printf("urlEncode [");
946 for (p=ps; *p!=0; p++)
947 printf("0x%02x ", (*p)&0xFF);
948 printf("]\n");
949
950 printf("urlEncode [%s] -> [%s]\n", ps, str);
951 }
952
954 free(str);
955}
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 957 of file mhttpd.cxx.

962{
963 std::string encoded;
964
965 const char* p = text;
966 while (*p) {
967 if (isalnum(*p)) {
968 encoded += *p++;
969 } else {
970 char buf[16];
971 sprintf(buf, "%%%02X", (*p)&0xFF);
972 encoded += buf;
973 p++;
974 }
975 }
976
977 if (/* DISABLES CODE */ (0)) {
978 printf("urlEncode [");
979 for (p=text; *p!=0; p++)
980 printf("0x%02x ", (*p)&0xFF);
981 printf("]\n");
982
983 printf("urlEncode [%s] -> [%s]\n", text, encoded.c_str());
984 }
985
986 return encoded;
987}
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 7916 of file mhttpd.cxx.

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

10089{
10090 int status = db_find_key(hDB, dir, str, hKey);
10091 if (status == DB_SUCCESS)
10092 return status;
10093
10094 db_create_key(hDB, dir, str, tid);
10095 status = db_find_key(hDB, dir, str, hKey);
10096 if (status != DB_SUCCESS || !*hKey) {
10097 cm_msg(MERROR, "xdb_find_key", "Invalid ODB path \"%s\"", str);
10098 str = "bad_xdb_find_key";
10099 db_create_key(hDB, dir, str, tid);
10100 db_find_key(hDB, dir, str, hKey);
10101 }
10102 assert(*hKey);
10103
10104 if (tid == TID_STRING) {
10105 db_set_data_index(hDB, *hKey, "", size, 0, TID_STRING);
10106 }
10107
10108 return status;
10109}
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 10072 of file mhttpd.cxx.

10073{
10074 HNDLE hKey;
10075 int status = db_find_key(hDB, 0, str, &hKey);
10076 if (status != DB_SUCCESS)
10077 return status;
10078
10079 KEY key;
10080 db_get_key(hDB, hKey, &key);
10081 if (index >= key.num_values)
10082 return DB_OUT_OF_RANGE;
10083
10084 status = db_get_data_index(hDB, hKey, value, &size, index, tid);
10085 return status;
10086}
#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 13792 of file mhttpd.cxx.

13792 {
13793 unsigned long now = (unsigned long) time(NULL);
13794 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13795 return now < val || now - val < 3600;
13796}
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 13803 of file mhttpd.cxx.

13804 {
13805 mg_printf(c,
13806 "HTTP/1.1 401 Unauthorized\r\n"
13807 "WWW-Authenticate: Digest qop=\"auth\", "
13808 "realm=\"%s\", nonce=\"%lu\"\r\n"
13809 "Content-Length: 0\r\n\r\n",
13810 domain, (unsigned long) time(NULL));
13811}
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 13771 of file mhttpd.cxx.

13775 {
13776 static const char colon[] = ":";
13777 static const size_t one = 1;
13778 char ha2[33];
13779
13780 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13781 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13782 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13783 colon, one, ha2, sizeof(ha2) - 1, NULL);
13784}
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 13467 of file mhttpd.cxx.

13467{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 3473 of file mhttpd.cxx.

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

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

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

◆ default_system_list

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

Definition at line 116 of file mhttpd.cxx.

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

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

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

◆ elog_mode

BOOL elog_mode = FALSE
static

Definition at line 94 of file mhttpd.cxx.

◆ favicon_ico

const unsigned char favicon_ico[]

Definition at line 282 of file mhttpd.cxx.

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

◆ favicon_png

const unsigned char favicon_png[]

Definition at line 217 of file mhttpd.cxx.

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

◆ gAllowedHosts

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

Definition at line 13479 of file mhttpd.cxx.

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13769 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8153 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8152 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8162 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

Definition at line 8163 of file mhttpd.cxx.

◆ gMimeTypesOdb

MVOdb* gMimeTypesOdb = NULL
static

Definition at line 179 of file mhttpd.cxx.

◆ gMimetypeTable

const MimetypeTableEntry gMimetypeTable[]

Definition at line 130 of file mhttpd.cxx.

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

◆ gMutex

std::mutex gMutex
static

Definition at line 47 of file mhttpd.cxx.

◆ gOdb

MVOdb* gOdb = NULL
static

Definition at line 48 of file mhttpd.cxx.

◆ gTraceBuf

RequestTraceBuf* gTraceBuf = NULL
static

Definition at line 506 of file mhttpd.cxx.

◆ history_mode

BOOL history_mode = FALSE
static

Definition at line 95 of file mhttpd.cxx.

◆ http_trace

int http_trace = 0
static

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

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13722 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13723 of file mhttpd.cxx.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

Definition at line 13724 of file mhttpd.cxx.

◆ verbose

BOOL verbose = FALSE
static

Definition at line 96 of file mhttpd.cxx.

◆ verbose_mg

bool verbose_mg = false
static

Definition at line 13720 of file mhttpd.cxx.