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)
 
char * stristr (const char *str, const char *pattern)
 
static double GetTimeSec ()
 
const char * mhttpd_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)
 
char * find_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 MVOdb * gOdb = NULL
 
static BOOL elog_mode = FALSE
 
static BOOL history_mode = FALSE
 
static BOOL verbose = FALSE
 
const char * mname []
 
static const char default_type_list [20][NAME_LENGTH]
 
static const char default_system_list [20][NAME_LENGTH]
 
const MimetypeTableEntry gMimetypeTable []
 
static MVOdb * gMimeTypesOdb = NULL
 
const unsigned char favicon_png []
 
const unsigned char favicon_ico []
 
static int http_trace = 0
 
static RequestTraceBufgTraceBuf = NULL
 
static const char * cgif_label_str []
 
static const char * cgif_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 8237 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 8238 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 8239 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 7631 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7632 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

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

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8325 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8324 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14258 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14257 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14256 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

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

3573{
3574 // do not append custom path to absolute filenames
3575
3576 if (filename[0] == '/')
3577 return filename;
3578 if (filename[0] == DIR_SEPARATOR)
3579 return filename;
3580
3581 HNDLE hDB;
3583
3584 std::string custom_path = "";
3585
3586 int status = db_get_value_string(hDB, 0, "/Custom/Path", 0, &custom_path, TRUE);
3587
3588 if (status != DB_SUCCESS)
3589 return filename;
3590
3591 if (custom_path.length() < 1)
3592 return filename;
3593
3594 if ((custom_path == DIR_SEPARATOR_STR) || !strchr(custom_path.c_str(), DIR_SEPARATOR)) {
3595 cm_msg(MERROR, "add_custom_path", "ODB /Custom/Path has a forbidden value \"%s\", please change it", custom_path.c_str());
3596 return filename;
3597 }
3598
3599 custom_path = ss_replace_env_variables(custom_path);
3600
3601 std::string full_filename = custom_path;
3602 if (full_filename[full_filename.length()-1] != DIR_SEPARATOR)
3603 full_filename += DIR_SEPARATOR_STR;
3604 full_filename += filename;
3605
3606 return full_filename;
3607}
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
#define DB_SUCCESS
Definition midas.h:632
#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:931
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:13967
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
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 9783 of file mhttpd.cxx.

9784{
9785 std::string s;
9786 s += name; // FIXME: should be URI-encoded
9787 s += "=";
9788 s += value; // FIXME: should be URI-encoded
9789 return s;
9790}
#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 16213 of file mhttpd.cxx.

16214{
16215 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16216 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16217}
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:16186
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16199
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 10380 of file mhttpd.cxx.

10381{
10382 int seln = atoi(p->getparam("seln"));
10383 for (int i=0; i<seln; i++) {
10384 char str[256];
10385 sprintf(str, "sel%d", i);
10386
10387 std::string par = p->getparam(str);
10388 if (par.length() < 1)
10389 continue;
10390
10391 std::string event_name, tag_name;
10392 SplitEventAndTagNames(par, event_name, tag_name);
10393
10394 if (tag_name == "")
10395 continue;
10396
10397 HistVar v;
10398
10399 v.event_name = event_name;
10400 v.tag_name = tag_name;
10401 v.colour = NextHistPlotColour(hp);
10402 v.order = NextHistPlotOrder(hp);
10403
10404 hp.vars.push_back(v);
10405 }
10406}
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:10154
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10119
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10145
char str[256]
Definition odbhist.cxx:33
std::vector< HistVar > vars
Definition mhttpd.cxx:8354
std::string tag_name
Definition mhttpd.cxx:8330
int order
Definition mhttpd.cxx:8335
std::string colour
Definition mhttpd.cxx:8332
std::string event_name
Definition mhttpd.cxx:8329
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 13895 of file mhttpd.cxx.

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

◆ check_obsolete_odb()

void check_obsolete_odb ( HNDLE  hDB,
const char *  odb_path 
)

Definition at line 1880 of file mhttpd.cxx.

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

13392{
13393 HNDLE hDB, hKeyEq, hKey;
13394 RUNINFO_STR(runinfo_str);
13395 int i, status;
13396 KEY key;
13397
13398 /* check /Runinfo structure */
13400 assert(status == DB_SUCCESS);
13401
13402 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13403 if (status == DB_STRUCT_MISMATCH) {
13404 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13405 if (status == DB_SUCCESS) {
13406 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13407 } else {
13408 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13409 return 0;
13410 }
13411 } else if (status == DB_NO_KEY) {
13412 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13413 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13414 if (status == DB_SUCCESS) {
13415 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13416 } else {
13417 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13418 return 0;
13419 }
13420 } else if (status != DB_SUCCESS) {
13421 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13422 return 0;
13423 }
13424
13425 /* check /Equipment/<name>/Common structures */
13426 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13427 for (i = 0 ;; i++) {
13428 db_enum_key(hDB, hKeyEq, i, &hKey);
13429 if (!hKey)
13430 break;
13431 db_get_key(hDB, hKey, &key);
13432
13434 if (status == DB_STRUCT_MISMATCH) {
13436 if (status == DB_SUCCESS) {
13437 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13438 } else {
13439 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13440 }
13441 } else if (status != DB_SUCCESS) {
13442 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13443 }
13444 }
13445 }
13446
13447 return CM_SUCCESS;
13448}
#define FALSE
Definition cfortran.h:309
#define CM_SUCCESS
Definition midas.h:582
#define DB_STRUCT_MISMATCH
Definition midas.h:655
#define DB_NO_KEY
Definition midas.h:643
#define MINFO
Definition midas.h:560
std::string strcomb1(const char **list)
Definition odb.cxx:668
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
Definition odb.cxx:13003
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6043
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5357
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
Definition odb.cxx:12831
KEY key
Definition mdump.cxx:34
#define EQUIPMENT_COMMON_STR
Definition midas.h:1112
#define RUNINFO_STR(_name)
Definition midas.h:1409
Definition midas.h:1027
char name[NAME_LENGTH]
Definition midas.h:1030
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 6739 of file mhttpd.cxx.

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

10037{
10038 return cmp_names(a.c_str(), b.c_str()) < 0;
10039}
static int cmp_names(const void *a, const void *b)
Definition mhttpd.cxx:9978
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 10041 of file mhttpd.cxx.

10042{
10043 return a < b;
10044}
Here is the caller graph for this function:

◆ cmp_names()

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

Definition at line 9978 of file mhttpd.cxx.

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

◆ cmp_tags()

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

Definition at line 10046 of file mhttpd.cxx.

10047{
10048 return cmp_names(a.name, b.name) < 0;
10049}
char name[NAME_LENGTH]
Definition midas.h:1234
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 10104 of file mhttpd.cxx.

10105{
10106 return a.order < b.order;
10107}
Here is the caller graph for this function:

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13455 of file mhttpd.cxx.

13456{
13457 _abort = true;
13458}
std::atomic_bool _abort
Definition mhttpd.cxx:13453
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14209 of file mhttpd.cxx.

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

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

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

13173{
13174 int len = strlen(query_string);
13175 char *buf = (char *)malloc(len+1);
13176 assert(buf != NULL);
13177 memcpy(buf, query_string, len+1);
13178 char* p = buf;
13179 p = strtok(p, "&");
13180 while (p != NULL) {
13181 char *pitem = p;
13182 p = strchr(p, '=');
13183 if (p != NULL) {
13184 *p++ = 0;
13185 urlDecode(pitem); // parameter name
13186 if (!equal_ustring(pitem, "format"))
13187 urlDecode(p); // parameter value
13188
13189 pp->setparam(pitem, p); // decoded query parameters
13190
13191 p = strtok(NULL, "&");
13192 }
13193 }
13194 free(buf);
13195}
void setparam(const char *param, const char *value)
Definition mhttpd.cxx:726
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
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 10484 of file mhttpd.cxx.

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

◆ do_jrpc()

void do_jrpc ( Param p,
Return r 
)

Definition at line 4322 of file mhttpd.cxx.

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

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

◆ do_jrpc_rev1()

void do_jrpc_rev1 ( Param p,
Return r 
)

Definition at line 4141 of file mhttpd.cxx.

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

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

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

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

13675{
13676 std::string exptdir = cm_get_path();
13677
13678 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13679 return SUCCESS;
13680
13681 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13682 return SUCCESS;
13683
13684 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13685 return SUCCESS;
13686
13687 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13688 return SUCCESS;
13689
13690 // setup default filename
13691 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13692 return SS_FILE_ERROR;
13693}
std::string cm_get_path()
Definition midas.cxx:1553
#define SS_FILE_ERROR
Definition midas.h:670
#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:13641
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 14144 of file mhttpd.cxx.

14145{
14146 size_t nlen = strlen(name);
14147 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14148 if (msg->header_names[i].len != nlen)
14149 continue;
14150 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14151 continue;
14152 return mgstr(&msg->header_values[i]);
14153 }
14154 return "";
14155}
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
static std::string mgstr(const mg_str *s)
Definition mhttpd.cxx:14139
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 3093 of file mhttpd.cxx.

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

◆ gen_odb_attachment()

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

Definition at line 2134 of file mhttpd.cxx.

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

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

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

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

16187{
16188 if (!params) {
16189 MJSO *doc = MJSO::I();
16190 doc->D("get current value of mhttpd http_trace");
16191 doc->P(NULL, 0, "there are no input parameters");
16192 doc->R(NULL, MJSON_INT, "current value of http_trace");
16193 return doc;
16194 }
16195
16196 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16197}
void D(const char *description)
Definition mjsonrpc.cxx:303
void P(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:340
MJsonNode * mjsonrpc_make_result(MJsonNode *node)
Definition mjsonrpc.cxx:135
static MJSO * I()
Definition mjsonrpc.cxx:298
void R(const char *name, int mjson_type, const char *description)
Definition mjsonrpc.cxx:348
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:5861
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;
379 gettimeofday(&tv, NULL);
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 14260 of file mhttpd.cxx.

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

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

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

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

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

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

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

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

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

◆ init_elog_odb()

void init_elog_odb ( )

Definition at line 1978 of file mhttpd.cxx.

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

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

◆ init_mhttpd_odb()

void init_mhttpd_odb ( MVOdb *  odb)

Definition at line 1930 of file mhttpd.cxx.

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

◆ interprete()

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

Definition at line 12253 of file mhttpd.cxx.

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

◆ is_editable()

BOOL is_editable ( char *  eq_name,
char *  var_name 
)

Definition at line 2531 of file mhttpd.cxx.

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

◆ javascript_commands()

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

Definition at line 4451 of file mhttpd.cxx.

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

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

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

12240{
12241 gMutex.lock();
12242 t->fTimeLocked = GetTimeSec();
12243}
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 16221 of file mhttpd.cxx.

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

14140{
14141 return std::string(s->p, s->len);
14142}
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:1500
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 9748 of file mhttpd.cxx.

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

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

◆ NextHistPlotOrder()

static int NextHistPlotOrder ( const HistPlot hp)
static

Definition at line 10145 of file mhttpd.cxx.

10146{
10147 int order = 0;
10148 for (size_t i=0; i<hp.vars.size(); i++)
10149 if (hp.vars[i].order > order)
10150 order = hp.vars[i].order;
10151 return order + 10;
10152}
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)
1074 xpath += DIR_SEPARATOR_STR;
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:7721
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 4376 of file mhttpd.cxx.

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

10110{
10111 printf("hist plot: %d variables\n", (int)hp.vars.size());
10112 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);
10113
10114 for (size_t i=0; i<hp.vars.size(); i++) {
10115 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);
10116 }
10117}

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

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

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

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

1449{
1450 redirect(r, path);
1451}
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 1435 of file mhttpd.cxx.

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

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

◆ search_callback()

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

Definition at line 1461 of file mhttpd.cxx.

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

7754{
7755 char mon[80];
7756 time_t t_sec;
7757
7758 t_sec = (time_t) sec;
7759
7760 struct tm tms;
7761 localtime_r(&t_sec, &tms);
7762 strcpy(mon, mname[tms.tm_mon]);
7763 mon[3] = 0;
7764
7765 if (force_date) {
7766 if (base < 600)
7767 sprintf(result, "%02d %s %02d %02d:%02d:%02d",
7768 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min,
7769 tms.tm_sec);
7770 else if (base < 3600 * 24)
7771 sprintf(result, "%02d %s %02d %02d:%02d",
7772 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7773 else
7774 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7775 } else {
7776 if (base < 600)
7777 sprintf(result, "%02d:%02d:%02d", tms.tm_hour, tms.tm_min, tms.tm_sec);
7778 else if (base < 3600 * 3)
7779 sprintf(result, "%02d:%02d", tms.tm_hour, tms.tm_min);
7780 else if (base < 3600 * 24)
7781 sprintf(result, "%02d %s %02d %02d:%02d",
7782 tms.tm_mday, mon, tms.tm_year % 100, tms.tm_hour, tms.tm_min);
7783 else
7784 sprintf(result, "%02d %s %02d", tms.tm_mday, mon, tms.tm_year % 100);
7785 }
7786}
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 12187 of file mhttpd.cxx.

12188{
12189 int length;
12190 const unsigned char *picon;
12191 char str[256], format[256];
12192 time_t now;
12193
12194 if (strstr(icon, "favicon.ico") != 0) {
12195 length = sizeof(favicon_ico);
12196 picon = favicon_ico;
12197 } else if (strstr(icon, "favicon.png") != 0) {
12198 length = sizeof(favicon_png);
12199 picon = favicon_png;
12200 } else
12201 return;
12202
12203 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
12204 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
12205 r->rsprintf("Accept-Ranges: bytes\r\n");
12206
12207 /* set expiration time to one day */
12208 time(&now);
12209 now += (int) (3600 * 24);
12210 struct tm gmt_tms;
12211 gmtime_r(&now, &gmt_tms);
12212 strcpy(format, "%A, %d-%b-%y %H:%M:%S GMT");
12213 strftime(str, sizeof(str), format, &gmt_tms);
12214 r->rsprintf("Expires: %s\r\n", str);
12215
12216 if (equal_ustring(icon, "favicon.ico"))
12217 r->rsprintf("Content-Type: image/x-icon\r\n");
12218 else
12219 r->rsprintf("Content-Type: image/png\r\n");
12220
12221 r->rsprintf("Content-Length: %d\r\n\r\n", length);
12222
12223 r->rmemcpy(picon, length);
12224}
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
1275 phe = gethostbyname(smtp_host);
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 assert(str != NULL);
1289
1290 recv_string(s, str, strsize, 3000);
1291 if (verbose)
1292 puts(str);
1293
1294 /* drain server messages */
1295 do {
1296 str[0] = 0;
1297 recv_string(s, str, strsize, 300);
1298 if (verbose)
1299 puts(str);
1300 } while (str[0]);
1301
1302 sprintf(str, "HELO %s\r\n", from_host);
1303 send(s, str, strlen(str), 0);
1304 if (verbose)
1305 puts(str);
1306 recv_string(s, str, strsize, 3000);
1307 if (verbose)
1308 puts(str);
1309
1310 if (strchr(from, '<')) {
1311 mstrlcpy(buf, strchr(from, '<') + 1, sizeof(buf));
1312 if (strchr(buf, '>'))
1313 *strchr(buf, '>') = 0;
1314 } else
1315 mstrlcpy(buf, from, sizeof(buf));
1316
1317 sprintf(str, "MAIL FROM: %s\n", buf);
1318 send(s, str, strlen(str), 0);
1319 if (verbose)
1320 puts(str);
1321 recv_string(s, str, strsize, 3000);
1322 if (verbose)
1323 puts(str);
1324
1325 sprintf(str, "RCPT TO: <%s>\r\n", to);
1326 send(s, str, strlen(str), 0);
1327 if (verbose)
1328 puts(str);
1329 recv_string(s, str, strsize, 3000);
1330 if (verbose)
1331 puts(str);
1332
1333 sprintf(str, "DATA\r\n");
1334 send(s, str, strlen(str), 0);
1335 if (verbose)
1336 puts(str);
1337 recv_string(s, str, strsize, 3000);
1338 if (verbose)
1339 puts(str);
1340
1341 sprintf(str, "To: %s\r\nFrom: %s\r\nSubject: %s\r\n", to, from, subject);
1342 send(s, str, strlen(str), 0);
1343 if (verbose)
1344 puts(str);
1345
1346 sprintf(str, "X-Mailer: mhttpd revision %s\r\n", mhttpd_revision());
1347 send(s, str, strlen(str), 0);
1348 if (verbose)
1349 puts(str);
1350
1351 ss_tzset(); // required for localtime_r()
1352 time_t now;
1353 time(&now);
1354 struct tm tms;
1355 localtime_r(&now, &tms);
1356 strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S", &tms);
1357 offset = (-(int) timezone);
1358 if (tms.tm_isdst)
1359 offset += 3600;
1360 sprintf(str, "Date: %s %+03d%02d\r\n", buf, (int) (offset / 3600),
1361 (int) ((abs((int) offset) / 60) % 60));
1362 send(s, str, strlen(str), 0);
1363 if (verbose)
1364 puts(str);
1365
1366 sprintf(str, "Content-Type: TEXT/PLAIN; charset=US-ASCII\r\n\r\n");
1367 send(s, str, strlen(str), 0);
1368 if (verbose)
1369 puts(str);
1370
1371 /* analyze text for "." at beginning of line */
1372 const char* p = text;
1373 str[0] = 0;
1374 while (strstr(p, "\r\n.\r\n")) {
1375 i = (POINTER_T) strstr(p, "\r\n.\r\n") - (POINTER_T) p + 1;
1376 mstrlcat(str, p, i);
1377 p += i + 4;
1378 mstrlcat(str, "\r\n..\r\n", strsize);
1379 }
1380 mstrlcat(str, p, strsize);
1381 mstrlcat(str, "\r\n", strsize);
1382 send(s, str, strlen(str), 0);
1383 if (verbose)
1384 puts(str);
1385
1386 /* send ".<CR>" to signal end of message */
1387 sprintf(str, ".\r\n");
1388 send(s, str, strlen(str), 0);
1389 if (verbose)
1390 puts(str);
1391 recv_string(s, str, strsize, 3000);
1392 if (verbose)
1393 puts(str);
1394
1395 sprintf(str, "QUIT\n");
1396 send(s, str, strlen(str), 0);
1397 if (verbose)
1398 puts(str);
1399 recv_string(s, str, strsize, 3000);
1400 if (verbose)
1401 puts(str);
1402
1403 closesocket(s);
1404 free(str);
1405
1406 return 1;
1407}
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 16199 of file mhttpd.cxx.

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

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

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

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

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

◆ show_elog_attachment()

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

Definition at line 2483 of file mhttpd.cxx.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ starts_with()

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

Definition at line 4435 of file mhttpd.cxx.

4436{
4437 if (s1.length() < strlen(s2))
4438 return false;
4439 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4440}
Here is the caller graph for this function:

◆ strencode()

void strencode ( Return r,
const char *  text 
)

Definition at line 2019 of file mhttpd.cxx.

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

◆ strencode2()

std::string strencode2 ( const char *  text)

Definition at line 2047 of file mhttpd.cxx.

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

◆ strencode3()

void strencode3 ( Return r,
const char *  text 
)

Definition at line 2078 of file mhttpd.cxx.

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

◆ strencode4()

void strencode4 ( Return r,
const char *  text 
)

Definition at line 2103 of file mhttpd.cxx.

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

◆ string_to_time()

time_t string_to_time ( const char *  str)

Definition at line 8120 of file mhttpd.cxx.

8121{
8122 time_t t = 0;
8123 for (; *str != 0; str++) {
8124 if (*str < '0')
8125 break;
8126 if (*str > '9')
8127 break;
8128 t *= 10;
8129 t += *str - '0';
8130 }
8131 return t;
8132}
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}

◆ submit_elog()

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

Definition at line 2248 of file mhttpd.cxx.

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

◆ taxis()

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

Definition at line 7788 of file mhttpd.cxx.

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

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

◆ time_to_string()

std::string time_to_string ( time_t  t)

Definition at line 8136 of file mhttpd.cxx.

8137{
8138 char buf[256];
8139 sprintf(buf, "%.0f", (double)t);
8140 return buf;
8141}
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 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 13641 of file mhttpd.cxx.

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

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12245 of file mhttpd.cxx.

12246{
12248 gMutex.unlock();
12249}
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 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 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
953 mstrlcpy(ps, str, ps_size);
954 free(str);
955}
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}

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

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

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

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

◆ xmg_check_nonce()

static int xmg_check_nonce ( const char *  nonce)
static

Definition at line 13778 of file mhttpd.cxx.

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

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

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

std::atomic_bool _abort {false}

Definition at line 13453 of file mhttpd.cxx.

13453{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",
NULL
}

Definition at line 3470 of file mhttpd.cxx.

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

◆ 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",
NULL
}

Definition at line 3430 of file mhttpd.cxx.

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

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

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13755 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8146 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8145 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8155 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

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

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13708 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13709 of file mhttpd.cxx.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

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