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 8242 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 8243 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 8244 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 7636 of file mhttpd.cxx.

◆ LOG2

#define LOG2   0.301029996

Definition at line 7637 of file mhttpd.cxx.

◆ LOG5

#define LOG5   0.698970005

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

◆ READ_HISTORY_LAST_WRITTEN

#define READ_HISTORY_LAST_WRITTEN   0x4

Definition at line 8330 of file mhttpd.cxx.

◆ READ_HISTORY_RUNMARKER

#define READ_HISTORY_RUNMARKER   0x2

Definition at line 8329 of file mhttpd.cxx.

◆ RESPONSE_501

#define RESPONSE_501   3

Definition at line 14263 of file mhttpd.cxx.

◆ RESPONSE_QUEUED

#define RESPONSE_QUEUED   2

Definition at line 14262 of file mhttpd.cxx.

◆ RESPONSE_SENT

#define RESPONSE_SENT   1

Definition at line 14261 of file mhttpd.cxx.

◆ STRDUP

#define STRDUP (   x)    strdup(x)

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

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

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

16219{
16220 mjsonrpc_add_handler("set_http_trace", set_http_trace);
16221 mjsonrpc_add_handler("get_http_trace", get_http_trace);
16222}
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:16191
static MJsonNode * set_http_trace(const MJsonNode *params)
Definition mhttpd.cxx:16204
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 10385 of file mhttpd.cxx.

10386{
10387 int seln = atoi(p->getparam("seln"));
10388 for (int i=0; i<seln; i++) {
10389 char str[256];
10390 sprintf(str, "sel%d", i);
10391
10392 std::string par = p->getparam(str);
10393 if (par.length() < 1)
10394 continue;
10395
10396 std::string event_name, tag_name;
10397 SplitEventAndTagNames(par, event_name, tag_name);
10398
10399 if (tag_name == "")
10400 continue;
10401
10402 HistVar v;
10403
10404 v.event_name = event_name;
10405 v.tag_name = tag_name;
10406 v.colour = NextHistPlotColour(hp);
10407 v.order = NextHistPlotOrder(hp);
10408
10409 hp.vars.push_back(v);
10410 }
10411}
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:10159
static std::string NextHistPlotColour(const HistPlot &hp)
Definition mhttpd.cxx:10124
static int NextHistPlotOrder(const HistPlot &hp)
Definition mhttpd.cxx:10150
char str[256]
Definition odbhist.cxx:33
std::vector< HistVar > vars
Definition mhttpd.cxx:8359
std::string tag_name
Definition mhttpd.cxx:8335
int order
Definition mhttpd.cxx:8340
std::string colour
Definition mhttpd.cxx:8337
std::string event_name
Definition mhttpd.cxx:8334
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 13900 of file mhttpd.cxx.

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

1886{
1887 HNDLE hKey;
1888 int status = db_find_key(hDB, 0, odb_path, &hKey);
1889 if (status == DB_SUCCESS) {
1890 cm_msg(MERROR, "check_obsolete_odb", "ODB \"%s\" is obsolete, please delete it.", odb_path);
1891 }
1892}
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 13396 of file mhttpd.cxx.

13397{
13398 HNDLE hDB, hKeyEq, hKey;
13399 RUNINFO_STR(runinfo_str);
13400 int i, status;
13401 KEY key;
13402
13403 /* check /Runinfo structure */
13405 assert(status == DB_SUCCESS);
13406
13407 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), FALSE);
13408 if (status == DB_STRUCT_MISMATCH) {
13409 status = db_check_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str(), TRUE);
13410 if (status == DB_SUCCESS) {
13411 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo corrected successfully");
13412 } else {
13413 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13414 return 0;
13415 }
13416 } else if (status == DB_NO_KEY) {
13417 cm_msg(MERROR, "check_odb_records", "ODB subtree /Runinfo does not exist");
13418 status = db_create_record(hDB, 0, "/Runinfo", strcomb1(runinfo_str).c_str());
13419 if (status == DB_SUCCESS) {
13420 cm_msg(MINFO, "check_odb_records", "ODB subtree /Runinfo created successfully");
13421 } else {
13422 cm_msg(MERROR, "check_odb_records", "Cannot create ODB subtree /Runinfo, db_create_record() status %d", status);
13423 return 0;
13424 }
13425 } else if (status != DB_SUCCESS) {
13426 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Runinfo, db_check_record() status %d", status);
13427 return 0;
13428 }
13429
13430 /* check /Equipment/<name>/Common structures */
13431 if (db_find_key(hDB, 0, "/equipment", &hKeyEq) == DB_SUCCESS) {
13432 for (i = 0 ;; i++) {
13433 db_enum_key(hDB, hKeyEq, i, &hKey);
13434 if (!hKey)
13435 break;
13436 db_get_key(hDB, hKey, &key);
13437
13439 if (status == DB_STRUCT_MISMATCH) {
13441 if (status == DB_SUCCESS) {
13442 cm_msg(MINFO, "check_odb_records", "ODB subtree /Equipment/%s/Common corrected successfully", key.name);
13443 } else {
13444 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13445 }
13446 } else if (status != DB_SUCCESS) {
13447 cm_msg(MERROR, "check_odb_records", "Cannot correct ODB subtree /Equipment/%s/Common, db_check_record() status %d", key.name, status);
13448 }
13449 }
13450 }
13451
13452 return CM_SUCCESS;
13453}
#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 6744 of file mhttpd.cxx.

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

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

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

◆ cmp_names()

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

Definition at line 9983 of file mhttpd.cxx.

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

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

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

◆ ctrlc_handler()

void ctrlc_handler ( int  sig)

Definition at line 13460 of file mhttpd.cxx.

13461{
13462 _abort = true;
13463}
std::atomic_bool _abort
Definition mhttpd.cxx:13458
Here is the caller graph for this function:

◆ decode_cookies()

void decode_cookies ( Cookies c,
const http_message msg 
)

Definition at line 14214 of file mhttpd.cxx.

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

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

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

13178{
13179 int len = strlen(query_string);
13180 char *buf = (char *)malloc(len+1);
13181 assert(buf != NULL);
13182 memcpy(buf, query_string, len+1);
13183 char* p = buf;
13184 p = strtok(p, "&");
13185 while (p != NULL) {
13186 char *pitem = p;
13187 p = strchr(p, '=');
13188 if (p != NULL) {
13189 *p++ = 0;
13190 urlDecode(pitem); // parameter name
13191 if (!equal_ustring(pitem, "format"))
13192 urlDecode(p); // parameter value
13193
13194 pp->setparam(pitem, p); // decoded query parameters
13195
13196 p = strtok(NULL, "&");
13197 }
13198 }
13199 free(buf);
13200}
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 10489 of file mhttpd.cxx.

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

◆ do_jrpc()

void do_jrpc ( Param p,
Return r 
)

Definition at line 4327 of file mhttpd.cxx.

4328{
4329 int status;
4330
4331 const char *name = p->getparam("name");
4332 const char *cmd = p->getparam("rcmd");
4333 const char *args = p->getparam("rarg");
4334
4335 if (!name || !cmd || !args) {
4337 r->rsprintf("<INVALID_ARGUMENTS>");
4338 return;
4339 }
4340
4342
4343 int buf_length = 1024;
4344
4345 int max_reply_length = atoi(p->getparam("max_reply_length"));
4346 if (max_reply_length > buf_length)
4347 buf_length = max_reply_length;
4348
4349 char* buf = (char*)malloc(buf_length);
4350 assert(buf != NULL);
4351
4352 buf[0] = 0;
4353
4354 HNDLE hconn;
4355
4356 status = cm_connect_client(name, &hconn);
4357
4358 if (status != RPC_SUCCESS) {
4359 r->rsprintf("<RPC_CONNECT_ERROR>%d</RPC_CONNECT_ERROR>", status);
4360 free(buf);
4361 return;
4362 }
4363
4364 status = rpc_client_call(hconn, RPC_JRPC, cmd, args, buf, buf_length);
4365
4366 if (status != RPC_SUCCESS) {
4367 r->rsprintf("<RPC_CALL_ERROR>%d</RPC_CALL_ERROR>", status);
4368 free(buf);
4369 return;
4370 }
4371
4372 r->rsprintf("%s", buf);
4373
4374 //status = cm_disconnect_client(hconn, FALSE);
4375
4376 free(buf);
4377}
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:1831
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 4021 of file mhttpd.cxx.

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

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

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

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

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

13680{
13681 std::string exptdir = cm_get_path();
13682
13683 if (try_file_mg(".", filename, path, fpp, trace) == SUCCESS)
13684 return SUCCESS;
13685
13686 if (try_file_mg(getenv("MIDAS_DIR"), filename, path, fpp, trace) == SUCCESS)
13687 return SUCCESS;
13688
13689 if (try_file_mg(exptdir.c_str(), filename, path, fpp, trace) == SUCCESS)
13690 return SUCCESS;
13691
13692 if (try_file_mg(getenv("MIDASSYS"), filename, path, fpp, trace) == SUCCESS)
13693 return SUCCESS;
13694
13695 // setup default filename
13696 try_file_mg(exptdir.c_str(), filename, path, NULL, false);
13697 return SS_FILE_ERROR;
13698}
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:13646
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 14149 of file mhttpd.cxx.

14150{
14151 size_t nlen = strlen(name);
14152 for (int i=0; i<MG_MAX_HTTP_HEADERS; i++) {
14153 if (msg->header_names[i].len != nlen)
14154 continue;
14155 if (strncmp(msg->header_names[i].p, name, nlen) != 0)
14156 continue;
14157 return mgstr(&msg->header_values[i]);
14158 }
14159 return "";
14160}
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:14144
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 3098 of file mhttpd.cxx.

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

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

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

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

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

16192{
16193 if (!params) {
16194 MJSO *doc = MJSO::I();
16195 doc->D("get current value of mhttpd http_trace");
16196 doc->P(NULL, 0, "there are no input parameters");
16197 doc->R(NULL, MJSON_INT, "current value of http_trace");
16198 return doc;
16199 }
16200
16201 return mjsonrpc_make_result("http_trace", MJsonNode::MakeInt(http_trace));
16202}
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 14265 of file mhttpd.cxx.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

12245{
12246 gMutex.lock();
12247 t->fTimeLocked = GetTimeSec();
12248}
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 16226 of file mhttpd.cxx.

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

14145{
14146 return std::string(s->p, s->len);
14147}
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 9753 of file mhttpd.cxx.

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

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

◆ NextHistPlotOrder()

static int NextHistPlotOrder ( const HistPlot hp)
static

Definition at line 10150 of file mhttpd.cxx.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1784{
1785 HNDLE hDB;
1786 time_t now;
1787 char str[256];
1788
1790
1791 /* header */
1792 r->rsprintf("HTTP/1.1 200 Document follows\r\n");
1793 r->rsprintf("Server: MIDAS HTTP %s\r\n", mhttpd_revision());
1794 r->rsprintf("Cache-control: private, max-age=0, no-cache\r\n");
1795 r->rsprintf("Expires: Fri, 01 Jan 1983 00:00:00 GMT\r\n");
1796 r->rsprintf("Content-Type: text/html; charset=%s\r\n\r\n", HTTP_ENCODING);
1797
1798 r->rsprintf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
1799 r->rsprintf("<html><head>\n");
1800
1801 /* style sheet */
1802 r->rsprintf("<link rel=\"icon\" href=\"favicon.png\" type=\"image/png\" />\n");
1803 r->rsprintf("<link rel=\"stylesheet\" href=\"mhttpd.css\" type=\"text/css\" />\n");
1804 r->rsprintf("<link rel=\"stylesheet\" href=\"midas.css\" type=\"text/css\" />\n");
1805
1806 /* auto refresh */
1807 if (refresh > 0)
1808 r->rsprintf("<meta http-equiv=\"Refresh\" content=\"%02d\">\n", refresh);
1809
1810 r->rsprintf("<title>%s</title></head>\n", title);
1811
1812 mstrlcpy(str, path, sizeof(str));
1813 urlEncode(str, sizeof(str));
1814
1815 if (equal_ustring(method, "POST"))
1816 r->rsprintf
1817 ("<body><form name=\"form1\" method=\"POST\" action=\"%s\" enctype=\"multipart/form-data\">\n\n",
1818 str);
1819 else if (equal_ustring(method, "GET"))
1820 r->rsprintf("<body><form name=\"form1\" method=\"GET\" action=\"%s\">\n\n", str);
1821
1822 /* title row */
1823
1824 std::string exptname;
1825 db_get_value_string(hDB, 0, "/Experiment/Name", 0, &exptname, TRUE);
1826 time(&now);
1827}
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(" <tr>\n");
1757 r->rsprintf(" <td style=\"text-align:right;\">MPlot custom plot examples:</td>\n");
1758 r->rsprintf(" <td style=\"text-align:left;\"><a href=\"?cmd=plot_example\">plot_example.html</a></td>\n");
1759 r->rsprintf(" </tr>\n");
1760
1761 r->rsprintf(" </table>\n");
1762 r->rsprintf(" </td>\n");
1763 r->rsprintf(" </tr>\n");
1764 r->rsprintf("</table>\n");
1765
1766 r->rsprintf("<table class=\"mtable\" style=\"width: 95%%\">\n");
1767 r->rsprintf(" <tr>\n");
1768 r->rsprintf(" <td class=\"mtableheader\">Contributions</td>\n");
1769 r->rsprintf(" </tr>\n");
1770 r->rsprintf(" <tr>\n");
1771 r->rsprintf(" <td>\n");
1772 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");
1773 r->rsprintf(" </td>\n");
1774 r->rsprintf(" </tr>\n");
1775 r->rsprintf("</table>\n");
1776
1777 r->rsprintf("</div></form>\n");
1778 r->rsprintf("</body></html>\r\n");
1779}
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 10527 of file mhttpd.cxx.

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

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

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

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

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

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

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

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

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

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

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

◆ starts_with()

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

Definition at line 4440 of file mhttpd.cxx.

4441{
4442 if (s1.length() < strlen(s2))
4443 return false;
4444 return (strncasecmp(s1.c_str(), s2, strlen(s2)) == 0);
4445}
Here is the caller graph for this function:

◆ strencode()

void strencode ( Return r,
const char *  text 
)

Definition at line 2024 of file mhttpd.cxx.

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

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

◆ strencode3()

void strencode3 ( Return r,
const char *  text 
)

Definition at line 2083 of file mhttpd.cxx.

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

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

◆ string_to_time()

time_t string_to_time ( const char *  str)

Definition at line 8125 of file mhttpd.cxx.

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

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

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

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

◆ time_to_string()

std::string time_to_string ( time_t  t)

Definition at line 8141 of file mhttpd.cxx.

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

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

◆ Unlock()

void Unlock ( RequestTrace t)

Definition at line 12250 of file mhttpd.cxx.

12251{
12253 gMutex.unlock();
12254}
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 7914 of file mhttpd.cxx.

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

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

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

13783 {
13784 unsigned long now = (unsigned long) time(NULL);
13785 unsigned long val = (unsigned long) strtoul(nonce, NULL, 16);
13786 return now < val || now - val < 3600;
13787}
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 13794 of file mhttpd.cxx.

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

13766 {
13767 static const char colon[] = ":";
13768 static const size_t one = 1;
13769 char ha2[33];
13770
13771 cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);
13772 cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,
13773 nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,
13774 colon, one, ha2, sizeof(ha2) - 1, NULL);
13775}
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 13458 of file mhttpd.cxx.

13458{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 3475 of file mhttpd.cxx.

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

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

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

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

◆ gAuthMg

Auth* gAuthMg = NULL
static

Definition at line 13760 of file mhttpd.cxx.

◆ gDoReloadHistory

bool gDoReloadHistory = false
static

Definition at line 8151 of file mhttpd.cxx.

◆ gDoSetupHistoryWatch

bool gDoSetupHistoryWatch = true
static

Definition at line 8150 of file mhttpd.cxx.

◆ gMh

MidasHistoryInterface* gMh = NULL
static

Definition at line 8160 of file mhttpd.cxx.

◆ gMhkey

HNDLE gMhkey = 0
static

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

◆ trace_mg_recv

bool trace_mg_recv = false
static

Definition at line 13713 of file mhttpd.cxx.

◆ trace_mg_send

bool trace_mg_send = false
static

Definition at line 13714 of file mhttpd.cxx.

◆ trace_mg_verbose

bool trace_mg_verbose = false
static

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