LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - clients.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 282 559 50.4 %
Date: 2021-01-13 20:07:21 Functions: 26 39 66.7 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * author Martin Kersten, Fabian Groffen
      11             :  * Client Management
      12             :  * Each online client is represented with an entry in the clients table.
      13             :  * The client may inspect his record at run-time and partially change its properties.
      14             :  * The administrator sees all client records and has the right to adjust global properties.
      15             :  */
      16             : 
      17             : 
      18             : #include "monetdb_config.h"
      19             : #include "clients.h"
      20             : #include "mcrypt.h"
      21             : #include "mal_scenario.h"
      22             : #include "mal_instruction.h"
      23             : #include "mal_runtime.h"
      24             : #include "mal_client.h"
      25             : #include "mal_authorize.h"
      26             : #include "mal_internal.h"
      27             : #include "gdk_time.h"
      28             : 
      29             : static int
      30           1 : pseudo(bat *ret, BAT *b, str X1,str X2) {
      31             :         char buf[BUFSIZ];
      32           1 :         snprintf(buf,BUFSIZ,"%s_%s", X1,X2);
      33           1 :         if (BBPindex(buf) <= 0 && BBPrename(b->batCacheid, buf) != 0)
      34             :                 return -1;
      35           1 :         if (BATroles(b,X2) != GDK_SUCCEED)
      36             :                 return -1;
      37           1 :         *ret = b->batCacheid;
      38           1 :         BBPkeepref(*ret);
      39           1 :         return 0;
      40             : }
      41             : 
      42             : str
      43           1 : CLTsetListing(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      44             : {
      45             :         (void) mb;
      46           1 :         *getArgReference_int(stk,pci,0) = cntxt->listing;
      47           1 :         cntxt->listing = *getArgReference_int(stk,pci,1);
      48           1 :         return MAL_SUCCEED;
      49             : }
      50             : 
      51             : str
      52           1 : CLTgetClientId(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      53             : {
      54             :         (void) mb;
      55           1 :         if(cntxt - mal_clients < 0 || cntxt - mal_clients >= MAL_MAXCLIENTS)
      56           0 :                 throw(MAL, "clients.getClientId", "Illegal client index");
      57           1 :         *getArgReference_int(stk,pci,0) = (int) (cntxt - mal_clients);
      58           1 :         return MAL_SUCCEED;
      59             : }
      60             : 
      61             : str
      62           0 : CLTgetScenario(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      63             : {
      64             :         (void) mb;
      65           0 :         if (cntxt->scenario)
      66           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup(cntxt->scenario);
      67             :         else
      68           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup("nil");
      69           0 :         if(*getArgReference_str(stk,pci,0) == NULL)
      70           0 :                 throw(MAL, "clients.getScenario", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      71             :         return MAL_SUCCEED;
      72             : }
      73             : 
      74             : str
      75           0 : CLTsetScenario(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      76             : {
      77             :         str msg = MAL_SUCCEED;
      78             : 
      79             :         (void) mb;
      80           0 :         msg = setScenario(cntxt, *getArgReference_str(stk,pci,1));
      81           0 :         *getArgReference_str(stk,pci,0) = 0;
      82           0 :         if (msg == NULL) {
      83           0 :                 *getArgReference_str(stk,pci,0) = GDKstrdup(cntxt->scenario);
      84           0 :                 if(*getArgReference_str(stk,pci,0) == NULL)
      85           0 :                         throw(MAL, "clients.setScenario", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      86             :         }
      87             :         return msg;
      88             : }
      89             : 
      90             : static void
      91           1 : CLTtimeConvert(time_t l, char *s)
      92             : {
      93           1 :         struct tm localt = (struct tm) {0};
      94             : 
      95           1 :         (void) localtime_r(&l, &localt);
      96             : 
      97             : #ifdef HAVE_ASCTIME_R3
      98             :         asctime_r(&localt, s, 26);
      99             : #else
     100           1 :         asctime_r(&localt, s);
     101             : #endif
     102           1 :         s[24] = 0;              /* remove newline */
     103           1 : }
     104             : 
     105             : str
     106           1 : CLTInfo(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     107             : {
     108           1 :         bat *ret=  getArgReference_bat(stk,pci,0);
     109             :         bat *ret2=  getArgReference_bat(stk,pci,0);
     110           1 :         BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT);
     111           1 :         BAT *bn = COLnew(0, TYPE_str, 12, TRANSIENT);
     112             :         char buf[32]; /* 32 bytes are enough */
     113             : 
     114             :         (void) mb;
     115           1 :         if (b == 0 || bn == 0){
     116           0 :                 if ( b != 0) BBPunfix(b->batCacheid);
     117           0 :                 if ( bn != 0) BBPunfix(bn->batCacheid);
     118           0 :                 throw(MAL, "clients.info", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     119             :         }
     120             : 
     121           1 :         (void) snprintf(buf, sizeof(buf), ""LLFMT"", (lng) cntxt->user);
     122           2 :         if (BUNappend(b, "user", false) != GDK_SUCCEED ||
     123           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     124           0 :                 goto bailout;
     125             : 
     126           2 :         if (BUNappend(b, "scenario", false) != GDK_SUCCEED ||
     127           1 :                 BUNappend(bn, cntxt->scenario, false) != GDK_SUCCEED)
     128           0 :                 goto bailout;
     129             : 
     130           1 :         (void) snprintf(buf, sizeof(buf), "%d", cntxt->listing);
     131           2 :         if (BUNappend(b, "listing", false) != GDK_SUCCEED ||
     132           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     133           0 :                 goto bailout;
     134             : 
     135           1 :         (void) snprintf(buf, sizeof(buf), "%d", cntxt->debug);
     136           2 :         if (BUNappend(b, "debug", false) != GDK_SUCCEED ||
     137           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     138           0 :                 goto bailout;
     139             : 
     140           1 :         CLTtimeConvert(cntxt->login, buf);
     141           2 :         if (BUNappend(b, "login", false) != GDK_SUCCEED ||
     142           1 :                 BUNappend(bn, buf, false) != GDK_SUCCEED)
     143           0 :                 goto bailout;
     144           1 :         if (pseudo(ret,b,"client","info"))
     145           0 :                 goto bailout;
     146           1 :         BBPkeepref(*ret2= bn->batCacheid);
     147           1 :         return MAL_SUCCEED;
     148             : 
     149           0 : bailout:
     150           0 :         BBPunfix(b->batCacheid);
     151           0 :         BBPunfix(bn->batCacheid);
     152           0 :         throw(MAL, "clients.info", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     153             : }
     154             : 
     155             : str
     156           0 : CLTLogin(bat *nme, bat *ret)
     157             : {
     158           0 :         BAT *b = COLnew(0, TYPE_str, 12, TRANSIENT);
     159           0 :         BAT *u = COLnew(0, TYPE_oid, 12, TRANSIENT);
     160             :         int i;
     161             :         char s[32];
     162             : 
     163           0 :         if (b == 0 || u == 0)
     164           0 :                 goto bailout;
     165             : 
     166           0 :         for (i = 0; i < MAL_MAXCLIENTS; i++) {
     167           0 :                 Client c = mal_clients+i;
     168           0 :                 if (c->mode >= RUNCLIENT && !is_oid_nil(c->user)) {
     169           0 :                         CLTtimeConvert(c->login, s);
     170           0 :                         if (BUNappend(b, s, false) != GDK_SUCCEED ||
     171           0 :                                 BUNappend(u, &c->user, false) != GDK_SUCCEED)
     172           0 :                                 goto bailout;
     173             :                 }
     174             :         }
     175           0 :         if (pseudo(ret,b,"client","login") ||
     176           0 :                 pseudo(nme,u,"client","name"))
     177           0 :                 goto bailout;
     178             :         return MAL_SUCCEED;
     179             : 
     180           0 : bailout:
     181           0 :         BBPreclaim(b);
     182           0 :         BBPreclaim(u);
     183           0 :         throw(MAL, "clients.getLogins", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     184             : }
     185             : 
     186             : str
     187           1 : CLTquit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     188             : {
     189             :         str msg = MAL_SUCCEED;
     190           1 :         int idx = cntxt->idx;
     191             :         (void) mb;              /* fool compiler */
     192             : 
     193           1 :         if ( pci->argc == 2 && cntxt->user == MAL_ADMIN)
     194           0 :                 idx = *getArgReference_int(stk,pci,1);
     195             : 
     196           1 :         if ( idx < 0 || idx > MAL_MAXCLIENTS)
     197           0 :                 throw(MAL,"clients.quit", "Illegal session id");
     198             : 
     199             :         /* A user can only quite a session under the same id */
     200           1 :         MT_lock_set(&mal_contextLock);
     201           1 :         if (mal_clients[idx].mode == FREECLIENT)
     202           0 :                 msg = createException(MAL,"clients.stop","Session not active anymore");
     203             :         else
     204           1 :                 mal_clients[idx].mode = FINISHCLIENT;
     205           1 :         MT_lock_unset(&mal_contextLock);
     206           1 :         return msg;
     207             : }
     208             : 
     209             : /* Stopping a client in a softmanner by setting the time out marker */
     210             : str
     211           0 : CLTstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     212             : {
     213           0 :         int idx = cntxt->idx;
     214             :         str msg = MAL_SUCCEED;
     215             : 
     216             :         (void) mb;
     217           0 :         if (cntxt->user == MAL_ADMIN)
     218           0 :                 idx = *getArgReference_int(stk,pci,1);
     219             : 
     220           0 :         if ( idx < 0 || idx > MAL_MAXCLIENTS)
     221           0 :                 throw(MAL,"clients.stop","Illegal session id");
     222             : 
     223           0 :         MT_lock_set(&mal_contextLock);
     224           0 :         if (mal_clients[idx].mode == FREECLIENT)
     225           0 :                 msg = createException(MAL,"clients.stop","Session not active anymore");
     226             :         else
     227           0 :                 mal_clients[idx].querytimeout = 1; /* stop client in one microsecond */
     228             :         /* this forces the designated client to stop at the next instruction */
     229           0 :         MT_lock_unset(&mal_contextLock);
     230           0 :         return msg;
     231             : }
     232             : 
     233             : str
     234           3 : CLTsetoptimizer(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     235             : {
     236           3 :         int idx = cntxt->idx;
     237             :         str opt, msg = MAL_SUCCEED;
     238             : 
     239             :         (void) mb;
     240           3 :         if( pci->argc == 3 && cntxt->user == MAL_ADMIN){
     241           1 :                 idx = *getArgReference_int(stk,pci,1);
     242           1 :                 opt = *getArgReference_str(stk,pci,2);
     243             :         } else {
     244           2 :                 opt = *getArgReference_str(stk,pci,1);
     245             :         }
     246             : 
     247           3 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     248           0 :                 throw(MAL,"clients.setoptimizer","Illegal session id");
     249           3 :         if (strNil(opt))
     250           0 :                 throw(MAL,"clients.setoptimizer","Input string cannot be NULL");
     251           3 :         if (strlen(opt) >= sizeof(mal_clients[idx].optimizer))
     252           0 :                 throw(MAL,"clients.setoptimizer","Input string is too large");
     253             : 
     254           3 :         MT_lock_set(&mal_contextLock);
     255           3 :         if (mal_clients[idx].mode == FREECLIENT)
     256           0 :                 msg = createException(MAL,"clients.setoptimizer","Session not active anymore");
     257             :         else
     258           3 :                 strcpy_len(mal_clients[idx].optimizer, opt, sizeof(mal_clients[idx].optimizer));
     259           3 :         MT_lock_unset(&mal_contextLock);
     260           3 :         return msg;
     261             : }
     262             : 
     263             : str
     264           3 : CLTsetworkerlimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     265             : {
     266             :         str msg = MAL_SUCCEED;
     267           3 :         int idx = cntxt->idx, limit;
     268             : 
     269             :         (void) mb;
     270           3 :         if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
     271           1 :                 idx = *getArgReference_int(stk,pci,1);
     272           1 :                 limit = *getArgReference_int(stk,pci,2);
     273             :         } else {
     274           2 :                 limit = *getArgReference_int(stk,pci,1);
     275             :         }
     276             : 
     277           3 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     278           0 :                 throw(MAL,"clients.setworkerlimit","Illegal session id");
     279           3 :         if( is_int_nil(limit))
     280           0 :                 throw(MAL, "clients.setworkerlimit","The number of workers cannot be NULL");
     281           3 :         if( limit < 0)
     282           1 :                 throw(MAL, "clients.setworkerlimit","The number of workers cannot be negative");
     283             : 
     284           2 :         MT_lock_set(&mal_contextLock);
     285           2 :         if (mal_clients[idx].mode == FREECLIENT)
     286           0 :                 msg = createException(MAL,"clients.setworkerlimit","Session not active anymore");
     287             :         else
     288           2 :                 mal_clients[idx].workerlimit = limit;
     289           2 :         MT_lock_unset(&mal_contextLock);
     290           2 :         return msg;
     291             : }
     292             : 
     293             : str
     294           3 : CLTsetmemorylimit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     295             : {
     296             :         str msg = MAL_SUCCEED;
     297           3 :         int idx = cntxt->idx, limit;
     298             : 
     299             :         (void) mb;
     300           3 :         if (pci->argc == 3 && cntxt->user == MAL_ADMIN){
     301           0 :                 idx = *getArgReference_sht(stk,pci,1);
     302           0 :                 limit = *getArgReference_int(stk,pci,2);
     303             :         } else {
     304           3 :                 limit = *getArgReference_int(stk,pci,1);
     305             :         }
     306             : 
     307           3 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     308           0 :                 throw(MAL,"clients.setmemorylimit","Illegal session id");
     309           3 :         if( is_int_nil(limit))
     310           0 :                 throw(MAL, "clients.setmemorylimit", "The memmory limit cannot be NULL");
     311           3 :         if( limit < 0)
     312           0 :                 throw(MAL, "clients.setmemorylimit", "The memmory limit cannot be negative");
     313             : 
     314           3 :         MT_lock_set(&mal_contextLock);
     315           3 :         if (mal_clients[idx].mode == FREECLIENT)
     316           0 :                 msg = createException(MAL,"clients.setmemorylimit","Session not active anymore");
     317             :         else
     318           3 :                 mal_clients[idx].memorylimit = limit;
     319           3 :         MT_lock_unset(&mal_contextLock);
     320           3 :         return msg;
     321             : }
     322             : 
     323             : str
     324           0 : CLTstopSession(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     325             : {
     326             :         str msg = MAL_SUCCEED;
     327           0 :         int idx = cntxt->idx;
     328             : 
     329           0 :         if (cntxt->user == MAL_ADMIN) {
     330           0 :                 switch( getArgType(mb,pci,1)){
     331           0 :                 case TYPE_bte:
     332           0 :                         idx = *getArgReference_bte(stk,pci,1);
     333           0 :                         break;
     334           0 :                 case TYPE_sht:
     335           0 :                         idx = *getArgReference_sht(stk,pci,1);
     336           0 :                         break;
     337           0 :                 case TYPE_int:
     338           0 :                         idx = *getArgReference_int(stk,pci,1);
     339           0 :                         break;
     340           0 :                 default:
     341           0 :                         throw(MAL,"clients.stopSession","Unexpected index type");
     342             :                 }
     343           0 :         }
     344           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     345           0 :                 throw(MAL,"clients.stopSession","Illegal session id");
     346             : 
     347           0 :         MT_lock_set(&mal_contextLock);
     348           0 :         if (mal_clients[idx].mode == FREECLIENT) {
     349           0 :                 msg = createException(MAL,"clients.stopSession","Session not active anymore");
     350             :         } else {
     351           0 :                 mal_clients[idx].querytimeout = 1; /* stop client in one microsecond */
     352           0 :                 mal_clients[idx].sessiontimeout = 1; /* stop client session */
     353             :         }
     354           0 :         MT_lock_unset(&mal_contextLock);
     355             :         /* this forces the designated client to stop at the next instruction */
     356           0 :         return msg;
     357             : }
     358             : 
     359             : /* Queries can be temporarily suspended */
     360             : str
     361           0 : CLTsuspend(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     362             : {
     363             :         str msg = MAL_SUCCEED;
     364           0 :         int idx = cntxt->idx;
     365             : 
     366           0 :         if (cntxt->user == MAL_ADMIN)
     367           0 :                 idx = *getArgReference_int(stk,pci,1);
     368             :         (void) mb;
     369             : 
     370           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     371           0 :                 throw(MAL,"clients.suspend", "Illegal session id");
     372             : 
     373           0 :         MT_lock_set(&mal_contextLock);
     374           0 :         if (mal_clients[idx].mode == FREECLIENT)
     375           0 :                 msg = createException(MAL,"clients.suspend","Session not active anymore");
     376             :         else
     377           0 :                 msg = MCsuspendClient(idx);
     378           0 :         MT_lock_unset(&mal_contextLock);
     379           0 :         return msg;
     380             : }
     381             : 
     382             : str
     383           0 : CLTwakeup(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     384             : {
     385             :         str msg = MAL_SUCCEED;
     386           0 :         int idx = cntxt->idx;
     387             : 
     388           0 :         if (cntxt->user == MAL_ADMIN)
     389           0 :                 idx = *getArgReference_int(stk,pci,1);
     390             :         (void) mb;
     391             : 
     392           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     393           0 :                 throw(MAL,"clients.wakeup", "Illegal session id");
     394             : 
     395           0 :         MT_lock_set(&mal_contextLock);
     396           0 :         if (mal_clients[idx].mode == FREECLIENT)
     397           0 :                 msg = createException(MAL,"clients.wakeup","Session not active anymore");
     398             :         else
     399           0 :                 msg = MCawakeClient(idx);
     400           0 :         MT_lock_unset(&mal_contextLock);
     401           0 :         return msg;
     402             : }
     403             : 
     404             : /* Set session time out based in seconds. As of December 2019, this function is deprecated */
     405             : str
     406           0 : CLTsetSessionTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     407             : {
     408             :         str msg = MAL_SUCCEED;
     409             :         lng sto;
     410           0 :         int idx = cntxt->idx;
     411             : 
     412             :         (void) mb;
     413           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     414           0 :                 throw(MAL,"clients.setsession","Illegal session id %d", idx);
     415           0 :         sto = *getArgReference_lng(stk,pci,1);
     416           0 :         if (is_lng_nil(sto))
     417           0 :                 throw(MAL,"clients.setsession","Session timeout cannot be NULL");
     418           0 :         if (sto < 0)
     419           0 :                 throw(MAL,"clients.setsession","Session timeout should be >= 0");
     420             : 
     421           0 :         MT_lock_set(&mal_contextLock);
     422           0 :         if (mal_clients[idx].mode == FREECLIENT)
     423           0 :                 msg = createException(MAL,"clients.setsession","Session not active anymore");
     424             :         else
     425           0 :                 mal_clients[idx].sessiontimeout = sto * 1000000;
     426           0 :         MT_lock_unset(&mal_contextLock);
     427           0 :         return msg;
     428             : }
     429             : 
     430             : /* Set the current query timeout in seconds. As of December 2019, this function is deprecated */
     431             : str
     432           0 : CLTsetTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     433             : {
     434             :         str msg = MAL_SUCCEED;
     435             :         lng qto,sto = 0;
     436           0 :         int idx = cntxt->idx;
     437             : 
     438             :         (void) mb;
     439           0 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     440           0 :                 throw(MAL,"clients.settimeout","Illegal session id %d", idx);
     441           0 :         qto = *getArgReference_lng(stk,pci,1);
     442           0 :         if (is_lng_nil(qto))
     443           0 :                 throw(MAL,"clients.settimeout","Query timeout cannot be NULL");
     444           0 :         if (qto < 0)
     445           0 :                 throw(MAL,"clients.settimeout","Query timeout should be >= 0");
     446           0 :         if (pci->argc == 3) {
     447           0 :                 sto = *getArgReference_lng(stk,pci,2);
     448           0 :                 if (is_lng_nil(sto))
     449           0 :                         throw(MAL,"clients.settimeout","Session timeout cannot be NULL");
     450           0 :                 if( sto < 0)
     451           0 :                         throw(MAL,"clients.settimeout","Session timeout should be >= 0");
     452             :         }
     453             : 
     454           0 :         MT_lock_set(&mal_contextLock);
     455           0 :         if (mal_clients[idx].mode == FREECLIENT) {
     456           0 :                 msg = createException(MAL, "clients.settimeout","Session not active anymore");
     457             :         } else {
     458           0 :                 if (pci->argc == 3)
     459           0 :                         mal_clients[idx].sessiontimeout = sto * 1000000;
     460           0 :                 mal_clients[idx].querytimeout = qto * 1000000;
     461             :         }
     462           0 :         MT_lock_unset(&mal_contextLock);
     463           0 :         return msg;
     464             : }
     465             : 
     466             : /* set session time out based in seconds, converted into microseconds */
     467             : str
     468          12 : CLTqueryTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     469             : {
     470             :         str msg = MAL_SUCCEED;
     471          12 :         int qto, idx = cntxt->idx;
     472             : 
     473          12 :         if (cntxt->user == MAL_ADMIN && pci->argc == 3){
     474           1 :                 switch( getArgType(mb,pci,1)){
     475           0 :                 case TYPE_bte:
     476           0 :                         idx = *getArgReference_bte(stk,pci,1);
     477           0 :                         break;
     478           0 :                 case TYPE_sht:
     479           0 :                         idx = *getArgReference_sht(stk,pci,1);
     480           0 :                         break;
     481           1 :                 case TYPE_int:
     482           1 :                         idx = *getArgReference_int(stk,pci,1);
     483           1 :                         break;
     484           0 :                 default:
     485           0 :                         throw(MAL,"clients.queryTimeout","Unexpected index type");
     486             :                 }
     487           1 :                 qto = *getArgReference_int(stk,pci,2);
     488             :         } else {
     489          11 :                 qto = *getArgReference_int(stk,pci,1);
     490             :         }
     491          12 :         if (is_int_nil(qto))
     492           0 :                 throw(MAL,"clients.queryTimeout","Query timeout cannot be NULL");
     493          12 :         if( qto < 0)
     494           1 :                 throw(MAL,"clients.queryTimeout","Query timeout should be >= 0");
     495             : 
     496          11 :         MT_lock_set(&mal_contextLock);
     497          11 :         if (mal_clients[idx].mode == FREECLIENT)
     498           0 :                 msg = createException(MAL,"clients.queryTimeout","Session not active anymore");
     499             :         else
     500          11 :                 mal_clients[idx].querytimeout = (lng) qto * 1000000;
     501          11 :         MT_lock_unset(&mal_contextLock);
     502          11 :         return msg;
     503             : }
     504             : 
     505             : /* Set the current session timeout in seconds */
     506             : str
     507           3 : CLTsessionTimeout(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     508             : {
     509             :         str msg = MAL_SUCCEED;
     510           3 :         int sto = -1, idx = cntxt->idx;
     511             : 
     512           3 :         if(cntxt->user == MAL_ADMIN && pci->argc == 3){
     513           1 :                 switch( getArgType(mb,pci,1)){
     514           0 :                 case TYPE_bte:
     515           0 :                         idx = *getArgReference_bte(stk,pci,1);
     516           0 :                         break;
     517           0 :                 case TYPE_sht:
     518           0 :                         idx = *getArgReference_sht(stk,pci,1);
     519           0 :                         break;
     520           1 :                 case TYPE_int:
     521           1 :                         idx = *getArgReference_int(stk,pci,1);
     522           1 :                         break;
     523           0 :                 default:
     524           0 :                         throw(MAL,"clients.sessionTimeout","Unexpected index type");
     525             :                 }
     526           1 :                 sto = *getArgReference_int(stk,pci,2);
     527             :         } else {
     528           2 :                 sto = *getArgReference_int(stk,pci,1);
     529             :         }
     530           3 :         if (is_int_nil(sto))
     531           0 :                 throw(MAL,"clients.sessionTimeout","Session timeout cannot be NULL");
     532           3 :         if( sto < 0)
     533           1 :                 throw(MAL,"clients.sessionTimeout","Session timeout should be >= 0");
     534           2 :         if( idx < 0 || idx > MAL_MAXCLIENTS)
     535           0 :                 throw(MAL,"clients.sessionTimeout","Illegal session id %d", idx);
     536             : 
     537           2 :         MT_lock_set(&mal_contextLock);
     538           2 :         if (mal_clients[idx].mode == FREECLIENT)
     539           0 :                 msg = createException(MAL,"clients.sessionTimeout","Session not active anymore");
     540             :         else
     541           2 :                 mal_clients[idx].sessiontimeout = (lng) sto * 1000000;
     542           2 :         MT_lock_unset(&mal_contextLock);
     543           2 :         return msg;
     544             : }
     545             : 
     546             : /* Retrieve the session time out */
     547             : str
     548           0 : CLTgetProfile(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     549             : {
     550           0 :         str *opt=  getArgReference_str(stk,pci,0);
     551           0 :         int *qto=  getArgReference_int(stk,pci,1);
     552           0 :         int *sto=  getArgReference_int(stk,pci,2);
     553           0 :         int *wlim=  getArgReference_int(stk,pci,3);
     554           0 :         int *mlim=  getArgReference_int(stk,pci,4);
     555             :         (void) mb;
     556           0 :         if (!(*opt = GDKstrdup(cntxt->optimizer)))
     557           0 :                 throw(MAL, "clients.getProfile", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     558           0 :         *qto = (int)(cntxt->querytimeout / 1000000);
     559           0 :         *sto = (int)(cntxt->sessiontimeout / 1000000);
     560           0 :         *wlim = cntxt->workerlimit;
     561           0 :         *mlim = cntxt->memorylimit;
     562           0 :         return MAL_SUCCEED;
     563             : }
     564             : 
     565             : /* Long running queries are traced in the logger
     566             :  * with a message from the interpreter.
     567             :  * This value should be set to minutes to avoid a lengthly log */
     568             : str
     569           0 : CLTsetPrintTimeout(void *ret, int *secs)
     570             : {
     571             :         (void) ret;
     572           0 :         if (is_int_nil(*secs))
     573           0 :                 setqptimeout(0);
     574             :         else
     575           0 :                 setqptimeout((lng) *secs * 60 * 1000000);
     576           0 :         return MAL_SUCCEED;
     577             : }
     578             : 
     579          13 : str CLTmd5sum(str *ret, str *pw) {
     580             : #ifdef HAVE_MD5_UPDATE
     581          26 :         if (strNil(*pw)) {
     582           1 :                 *ret = GDKstrdup(str_nil);
     583             :         } else {
     584          12 :                 char *mret = mcrypt_MD5Sum(*pw, strlen(*pw));
     585             : 
     586          12 :                 if (!mret)
     587           0 :                         throw(MAL, "clients.md5sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     588          12 :                 *ret = GDKstrdup(mret);
     589          12 :                 free(mret);
     590             :         }
     591          13 :         if (*ret == NULL)
     592           0 :                 throw(MAL, "clients.md5sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     593             :         return MAL_SUCCEED;
     594             : #else
     595             :         (void) ret;
     596             :         (void) pw;
     597             :         throw(MAL, "clients.md5sum", SQLSTATE(0A000) PROGRAM_NYI);
     598             : #endif
     599             : }
     600             : 
     601           1 : str CLTsha1sum(str *ret, str *pw) {
     602             : #ifdef HAVE_SHA1_UPDATE
     603           2 :         if (strNil(*pw)) {
     604           0 :                 *ret = GDKstrdup(str_nil);
     605             :         } else {
     606           1 :                 char *mret = mcrypt_SHA1Sum(*pw, strlen(*pw));
     607             : 
     608           1 :                 if (!mret)
     609           0 :                         throw(MAL, "clients.sha1sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     610           1 :                 *ret = GDKstrdup(mret);
     611           1 :                 free(mret);
     612             :         }
     613           1 :         if (*ret == NULL)
     614           0 :                 throw(MAL, "clients.sha1sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     615             :         return MAL_SUCCEED;
     616             : #else
     617             :         (void) ret;
     618             :         (void) pw;
     619             :         throw(MAL, "clients.sha1sum", SQLSTATE(0A000) PROGRAM_NYI);
     620             : #endif
     621             : }
     622             : 
     623           1 : str CLTripemd160sum(str *ret, str *pw) {
     624             : #ifdef HAVE_RIPEMD160_UPDATE
     625           2 :         if (strNil(*pw)) {
     626           0 :                 *ret = GDKstrdup(str_nil);
     627             :         } else {
     628           1 :                 char *mret = mcrypt_RIPEMD160Sum(*pw, strlen(*pw));
     629             : 
     630           1 :                 if (!mret)
     631           0 :                         throw(MAL, "clients.ripemd160sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     632           1 :                 *ret = GDKstrdup(mret);
     633           1 :                 free(mret);
     634             :         }
     635           1 :         if (*ret == NULL)
     636           0 :                 throw(MAL, "clients.ripemd160sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     637             :         return MAL_SUCCEED;
     638             : #else
     639             :         (void) ret;
     640             :         (void) pw;
     641             :         throw(MAL, "clients.ripemd160sum", SQLSTATE(0A000) PROGRAM_NYI);
     642             : #endif
     643             : }
     644             : 
     645           4 : str CLTsha2sum(str *ret, str *pw, int *bits) {
     646           8 :         if (strNil(*pw) || is_int_nil(*bits)) {
     647           0 :                 *ret = GDKstrdup(str_nil);
     648             :         } else {
     649             :                 char *mret = 0;
     650           4 :                 switch (*bits) {
     651             : #ifdef HAVE_SHA512_UPDATE
     652           1 :                         case 512:
     653           1 :                                 mret = mcrypt_SHA512Sum(*pw, strlen(*pw));
     654           1 :                                 break;
     655             : #endif
     656             : #ifdef HAVE_SHA384_UPDATE
     657           1 :                         case 384:
     658           1 :                                 mret = mcrypt_SHA384Sum(*pw, strlen(*pw));
     659           1 :                                 break;
     660             : #endif
     661             : #ifdef HAVE_SHA256_UPDATE
     662           1 :                         case 256:
     663           1 :                                 mret = mcrypt_SHA256Sum(*pw, strlen(*pw));
     664           1 :                                 break;
     665             : #endif
     666             : #ifdef HAVE_SHA224_UPDATE
     667           1 :                         case 224:
     668           1 :                                 mret = mcrypt_SHA224Sum(*pw, strlen(*pw));
     669           1 :                                 break;
     670             : #endif
     671           0 :                         default:
     672             :                                 (void)mret;
     673           0 :                                 throw(ILLARG, "clients.sha2sum", "wrong number of bits "
     674             :                                                 "for SHA2 sum: %d", *bits);
     675             :                 }
     676             : #if defined(HAVE_SHA512_UPDATE) || defined(HAVE_SHA384_UPDATE) || defined(HAVE_SHA256_UPDATE) || defined(HAVE_SHA224_UPDATE)
     677           4 :                 if (!mret)
     678           0 :                         throw(MAL, "clients.sha2sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     679           4 :                 *ret = GDKstrdup(mret);
     680           4 :                 free(mret);
     681             : #endif
     682             :         }
     683           4 :         if (*ret == NULL)
     684           0 :                 throw(MAL, "clients.sha2sum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     685             :         return MAL_SUCCEED;
     686             : }
     687             : 
     688           1 : str CLTbackendsum(str *ret, str *pw) {
     689           2 :         if (strNil(*pw)) {
     690           0 :                 *ret = GDKstrdup(str_nil);
     691             :         } else {
     692           1 :                 char *mret = mcrypt_BackendSum(*pw, strlen(*pw));
     693           1 :                 if (mret == NULL)
     694           0 :                         throw(MAL, "clients.backendsum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     695           1 :                 *ret = GDKstrdup(mret);
     696           1 :                 free(mret);
     697             :         }
     698           1 :         if (*ret == NULL)
     699           0 :                 throw(MAL, "clients.backendsum", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     700             :         return MAL_SUCCEED;
     701             : }
     702             : 
     703           3 : str CLTaddUser(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     704           3 :         oid *ret = getArgReference_oid(stk, pci, 0);
     705           3 :         str *usr = getArgReference_str(stk, pci, 1);
     706           3 :         str *pw = getArgReference_str(stk, pci, 2);
     707             : 
     708             :         (void)mb;
     709             : 
     710           3 :         return AUTHaddUser(ret, cntxt, *usr, *pw);
     711             : }
     712             : 
     713           1 : str CLTremoveUser(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     714             :         str *usr;
     715             :         (void)mb;
     716             : 
     717           1 :         usr = getArgReference_str(stk, pci, 1);
     718             : 
     719           1 :         return AUTHremoveUser(cntxt, *usr);
     720             : }
     721             : 
     722           5 : str CLTgetUsername(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     723           5 :         str *ret = getArgReference_str(stk, pci, 0);
     724             :         (void)mb;
     725             : 
     726           5 :         return AUTHgetUsername(ret, cntxt);
     727             : }
     728             : 
     729           1 : str CLTgetPasswordHash(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     730           1 :         str *ret = getArgReference_str(stk, pci, 0);
     731           1 :         str *user = getArgReference_str(stk, pci, 1);
     732             : 
     733             :         (void)mb;
     734             : 
     735           1 :         return AUTHgetPasswordHash(ret, cntxt, *user);
     736             : }
     737             : 
     738           0 : str CLTchangeUsername(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     739           0 :         str *old = getArgReference_str(stk, pci, 1);
     740           0 :         str *new = getArgReference_str(stk, pci, 2);
     741             : 
     742             :         (void)mb;
     743             : 
     744           0 :         return AUTHchangeUsername(cntxt, *old, *new);
     745             : }
     746             : 
     747           0 : str CLTchangePassword(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     748           0 :         str *old = getArgReference_str(stk, pci, 1);
     749           0 :         str *new = getArgReference_str(stk, pci, 2);
     750             : 
     751             :         (void)mb;
     752             : 
     753           0 :         return AUTHchangePassword(cntxt, *old, *new);
     754             : }
     755             : 
     756           2 : str CLTsetPassword(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     757           2 :         str *usr = getArgReference_str(stk, pci, 1);
     758           2 :         str *new = getArgReference_str(stk, pci, 2);
     759             : 
     760             :         (void)mb;
     761             : 
     762           2 :         return AUTHsetPassword(cntxt, *usr, *new);
     763             : }
     764             : 
     765           3 : str CLTcheckPermission(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     766             : #ifdef HAVE_SHA1_UPDATE
     767           3 :         str *usr = getArgReference_str(stk, pci, 1);
     768           3 :         str *pw = getArgReference_str(stk, pci, 2);
     769             :         str ch = "";
     770             :         str algo = "SHA1";
     771             :         oid id;
     772             :         str pwd,msg;
     773             : 
     774             :         (void)mb;
     775             : 
     776           3 :         if (!(pwd = mcrypt_SHA1Sum(*pw, strlen(*pw))))
     777           0 :                 throw(MAL, "clients.checkPermission", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     778           3 :         msg = AUTHcheckCredentials(&id, cntxt, *usr, pwd, ch, algo);
     779           3 :         free(pwd);
     780           3 :         return msg;
     781             : #else
     782             :         (void) cntxt;
     783             :         (void) mb;
     784             :         (void) stk;
     785             :         (void) pci;
     786             :         throw(MAL, "mal.checkPermission", "Required digest algorithm SHA-1 missing");
     787             : #endif
     788             : }
     789             : 
     790           2 : str CLTgetUsers(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     791           2 :         bat *ret1 = getArgReference_bat(stk, pci, 0);
     792           2 :         bat *ret2 = getArgReference_bat(stk, pci, 1);
     793             :         BAT *uid, *nme;
     794             :         str tmp;
     795             : 
     796             :         (void)mb;
     797             : 
     798           2 :         tmp = AUTHgetUsers(&uid, &nme, cntxt);
     799           2 :         if (tmp)
     800             :                 return tmp;
     801           2 :         BBPkeepref(*ret1 = uid->batCacheid);
     802           2 :         BBPkeepref(*ret2 = nme->batCacheid);
     803           2 :         return(MAL_SUCCEED);
     804             : }
     805             : 
     806             : str
     807           1 : CLTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) {
     808           1 :         str *ret  = getArgReference_str(stk,pci,0);
     809             :         int delay;
     810             :         bit force = FALSE;
     811             :         int leftover;
     812           1 :         char buf[1024]={"safe to stop last connection"};
     813             : 
     814           1 :         if ( pci->argc == 3)
     815           0 :                 force = *getArgReference_bit(stk,pci,2);
     816             : 
     817             :         (void) mb;
     818           1 :         switch( getArgType(mb,pci,1)){
     819           1 :         case TYPE_bte:
     820           1 :                 delay = *getArgReference_bte(stk,pci,1);
     821           1 :                 break;
     822           0 :         case TYPE_sht:
     823           0 :                 delay = *getArgReference_sht(stk,pci,1);
     824           0 :                 break;
     825           0 :         default:
     826           0 :                 delay = *getArgReference_int(stk,pci,1);
     827           0 :                 break;
     828             :         }
     829             : 
     830           1 :         if (cntxt->user != MAL_ADMIN)
     831           0 :                 throw(MAL,"mal.shutdown", "Administrator rights required");
     832           1 :         if (is_int_nil(delay))
     833           0 :                 throw(MAL,"mal.shutdown", "Delay cannot be NULL");
     834           1 :         if (delay < 0)
     835           0 :                 throw(MAL,"mal.shutdown", "Delay cannot be negative");
     836           1 :         if (is_bit_nil(force))
     837           0 :                 throw(MAL,"mal.shutdown", "Force cannot be NULL");
     838           1 :         MCstopClients(cntxt);
     839             :         do{
     840           1 :                 if ( (leftover = MCactiveClients()-1) )
     841           0 :                         MT_sleep_ms(1000);
     842           1 :                 delay --;
     843           1 :         } while (delay > 0 && leftover > 1);
     844           1 :         if( delay == 0 && leftover > 1)
     845           0 :                 snprintf(buf, 1024,"%d client sessions still running",leftover);
     846           1 :         *ret = GDKstrdup(buf);
     847           1 :         if ( force)
     848           0 :                 mal_exit(0);
     849           1 :         if (*ret == NULL)
     850           0 :                 throw(MAL, "mal.shutdown", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     851             :         return MAL_SUCCEED;
     852             : }
     853             : 
     854             : str
     855          13 : CLTsessions(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     856             : {
     857             :         BAT *id = NULL, *user = NULL, *login = NULL, *sessiontimeout = NULL, *querytimeout = NULL, *idle= NULL;
     858             :         BAT *opt = NULL, *wlimit = NULL, *mlimit = NULL;
     859          13 :         bat *idId = getArgReference_bat(stk,pci,0);
     860          13 :         bat *userId = getArgReference_bat(stk,pci,1);
     861          13 :         bat *loginId = getArgReference_bat(stk,pci,2);
     862          13 :         bat *idleId = getArgReference_bat(stk,pci,3);
     863          13 :         bat *optId = getArgReference_bat(stk,pci,4);
     864          13 :         bat *sessiontimeoutId = getArgReference_bat(stk,pci,5);
     865          13 :         bat *querytimeoutId = getArgReference_bat(stk,pci,6);
     866          13 :         bat *wlimitId = getArgReference_bat(stk,pci,7);
     867          13 :         bat *mlimitId = getArgReference_bat(stk,pci,8);
     868             :         Client c;
     869             :         timestamp ret;
     870             :         int timeout;
     871             :         str msg = NULL;
     872             : 
     873             :         (void) cntxt;
     874             :         (void) mb;
     875             : 
     876          13 :         id = COLnew(0, TYPE_int, 0, TRANSIENT);
     877          13 :         user = COLnew(0, TYPE_str, 0, TRANSIENT);
     878          13 :         login = COLnew(0, TYPE_timestamp, 0, TRANSIENT);
     879          13 :         opt = COLnew(0, TYPE_str, 0, TRANSIENT);
     880          13 :         sessiontimeout = COLnew(0, TYPE_int, 0, TRANSIENT);
     881          13 :         querytimeout = COLnew(0, TYPE_int, 0, TRANSIENT);
     882          13 :         wlimit = COLnew(0, TYPE_int, 0, TRANSIENT);
     883          13 :         mlimit = COLnew(0, TYPE_int, 0, TRANSIENT);
     884          13 :         idle = COLnew(0, TYPE_timestamp, 0, TRANSIENT);
     885             : 
     886          13 :         if (id == NULL || user == NULL || login == NULL || sessiontimeout == NULL || idle == NULL || querytimeout == NULL ||
     887          13 :            opt == NULL || wlimit == NULL || mlimit == NULL ){
     888           0 :                 if ( id) BBPunfix(id->batCacheid);
     889           0 :                 if ( user) BBPunfix(user->batCacheid);
     890           0 :                 if ( login) BBPunfix(login->batCacheid);
     891           0 :                 if ( sessiontimeout) BBPunfix(sessiontimeout->batCacheid);
     892           0 :                 if ( querytimeout) BBPunfix(querytimeout->batCacheid);
     893           0 :                 if ( idle) BBPunfix(idle->batCacheid);
     894             : 
     895           0 :                 if ( opt) BBPunfix(opt->batCacheid);
     896           0 :                 if ( wlimit) BBPunfix(wlimit->batCacheid);
     897           0 :                 if ( mlimit) BBPunfix(mlimit->batCacheid);
     898           0 :                 throw(SQL,"sql.sessions", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     899             :         }
     900             : 
     901          13 :         MT_lock_set(&mal_contextLock);
     902             : 
     903         845 :         for (c = mal_clients; c < mal_clients + MAL_MAXCLIENTS; c++) {
     904         832 :                 if (c->mode == RUNCLIENT) {
     905          13 :                         if (BUNappend(user, c->username, false) != GDK_SUCCEED)
     906           0 :                                 goto bailout;
     907          13 :                         ret = timestamp_fromtime(c->login);
     908          13 :                         if (is_timestamp_nil(ret)) {
     909           0 :                                 msg = createException(SQL, "sql.sessions", SQLSTATE(22003) "Failed to convert user logged time");
     910           0 :                                 goto bailout;
     911             :                         }
     912          13 :                         if (BUNappend(id, &c->idx, false) != GDK_SUCCEED)
     913           0 :                                 goto bailout;
     914          13 :                         if (BUNappend(login, &ret, false) != GDK_SUCCEED)
     915           0 :                                 goto bailout;
     916          13 :                         timeout = (int)(c->sessiontimeout / 1000000);
     917          13 :                         if (BUNappend(sessiontimeout, &timeout, false) != GDK_SUCCEED)
     918           0 :                                 goto bailout;
     919          13 :                         timeout = (int)(c->querytimeout / 1000000);
     920          13 :                         if (BUNappend(querytimeout, &timeout, false) != GDK_SUCCEED)
     921           0 :                                 goto bailout;
     922          13 :                         if( c->idle){
     923           0 :                                 ret = timestamp_fromtime(c->idle);
     924           0 :                                 if (is_timestamp_nil(ret)) {
     925           0 :                                         msg = createException(SQL, "sql.sessions", SQLSTATE(22003) "Failed to convert user logged time");
     926           0 :                                         goto bailout;
     927             :                                 }
     928             :                         } else
     929          13 :                                 ret = timestamp_nil;
     930          13 :                         if (BUNappend(idle, &ret, false) != GDK_SUCCEED)
     931           0 :                                 goto bailout;
     932          13 :                         if (BUNappend(opt, &c->optimizer, false) != GDK_SUCCEED)
     933           0 :                                 goto bailout;
     934          13 :                         if (BUNappend(wlimit, &c->workerlimit, false) != GDK_SUCCEED)
     935           0 :                                 goto bailout;
     936          13 :                         if (BUNappend(mlimit, &c->memorylimit, false) != GDK_SUCCEED)
     937           0 :                                 goto bailout;
     938             :                 }
     939             :         }
     940          13 :         MT_lock_unset(&mal_contextLock);
     941          13 :         BBPkeepref(*idId = id->batCacheid);
     942          13 :         BBPkeepref(*userId = user->batCacheid);
     943          13 :         BBPkeepref(*loginId = login->batCacheid);
     944          13 :         BBPkeepref(*sessiontimeoutId = sessiontimeout->batCacheid);
     945          13 :         BBPkeepref(*querytimeoutId = querytimeout->batCacheid);
     946          13 :         BBPkeepref(*idleId = idle->batCacheid);
     947             : 
     948          13 :         BBPkeepref(*optId = opt->batCacheid);
     949          13 :         BBPkeepref(*wlimitId = wlimit->batCacheid);
     950          13 :         BBPkeepref(*mlimitId = mlimit->batCacheid);
     951          13 :         return MAL_SUCCEED;
     952             : 
     953           0 : bailout:
     954           0 :         MT_lock_unset(&mal_contextLock);
     955           0 :         BBPunfix(id->batCacheid);
     956           0 :         BBPunfix(user->batCacheid);
     957           0 :         BBPunfix(login->batCacheid);
     958           0 :         BBPunfix(sessiontimeout->batCacheid);
     959           0 :         BBPunfix(querytimeout->batCacheid);
     960           0 :         BBPunfix(idle->batCacheid);
     961             : 
     962           0 :         BBPunfix(opt->batCacheid);
     963           0 :         BBPunfix(wlimit->batCacheid);
     964           0 :         BBPunfix(mlimit->batCacheid);
     965           0 :         return msg;
     966             : }
     967             : 
     968             : #include "mel.h"
     969             : mel_func clients_init_funcs[] = {
     970             :  pattern("clients", "setListing", CLTsetListing, false, "Turn on/off echo of MAL instructions:\n1 - echo input,\n2 - show mal instruction,\n4 - show details of type resolutoin, \n8 - show binding information.", args(1,2, arg("",int),arg("flag",int))),
     971             :  pattern("clients", "getId", CLTgetClientId, false, "Return a number that uniquely represents the current client.", args(1,1, arg("",int))),
     972             :  pattern("clients", "getInfo", CLTInfo, false, "Pseudo bat with client attributes.", args(2,2, batarg("",str),batarg("",str))),
     973             :  pattern("clients", "getScenario", CLTgetScenario, false, "Retrieve current scenario name.", args(1,1, arg("",str))),
     974             :  pattern("clients", "setScenario", CLTsetScenario, false, "Switch to other scenario handler, return previous one.", args(1,2, arg("",str),arg("msg",str))),
     975             :  pattern("clients", "quit", CLTquit, false, "Terminate the client session.", args(1,1, arg("",void))),
     976             :  pattern("clients", "quit", CLTquit, false, "Terminate the session for a single client using a soft error.\nIt is the privilige of the console user.", args(1,2, arg("",void),arg("idx",int))),
     977             :  command("clients", "getLogins", CLTLogin, false, "Pseudo bat of client id and login time.", args(2,2, batarg("user",oid),batarg("start",str))),
     978             :  pattern("clients", "stop", CLTstop, false, "Stop the query execution at the next eligble statement.", args(0,1, arg("id",int))),
     979             :  pattern("clients", "suspend", CLTsuspend, false, "Put a client process to sleep for some time.\nIt will simple sleep for a second at a time, until\nthe awake bit has been set in its descriptor", args(1,2, arg("",void),arg("id",int))),
     980             :  pattern("clients", "wakeup", CLTwakeup, false, "Wakeup a client process", args(1,2, arg("",void),arg("id",int))),
     981             :  pattern("clients", "getprofile", CLTgetProfile, false, "Retrieve the profile settings for a client", args(5,5, arg("opt",str),arg("q",int),arg("s",int),arg("w",int),arg("m",int))),
     982             :  pattern("clients", "setsession", CLTsetSessionTimeout, false, "Abort a session after  n seconds.", args(1,2, arg("",void),arg("n",lng))),
     983             :  pattern("clients", "settimeout", CLTsetTimeout, false, "Abort a query after  n seconds.", args(1,2, arg("",void),arg("n",lng))),
     984             :  pattern("clients", "settimeout", CLTsetTimeout, false, "Abort a query after q seconds (q=0 means run undisturbed).\nThe session timeout aborts the connection after spending too\nmany seconds on query processing.", args(1,3, arg("",void),arg("q",lng),arg("s",lng))),
     985             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,2, arg("",void),arg("n",int))),
     986             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,3, arg("",void),arg("sid",bte),arg("n",int))),
     987             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "", args(1,3, arg("",void),arg("sid",sht),arg("n",int))),
     988             :  pattern("clients", "setquerytimeout", CLTqueryTimeout, false, "A query is aborted after q seconds (q=0 means run undisturbed).", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
     989             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,2, arg("",void),arg("n",int))),
     990             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,3, arg("",void),arg("sid",bte),arg("n",int))),
     991             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "", args(1,3, arg("",void),arg("sid",sht),arg("n",int))),
     992             :  pattern("clients", "setsessiontimeout", CLTsessionTimeout, false, "Set the session timeout for a particulat session id", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
     993             :  pattern("clients", "setoptimizer", CLTsetoptimizer, false, "", args(1,2, arg("",void),arg("opt",str))),
     994             :  pattern("clients", "setoptimizer", CLTsetoptimizer, false, "Set the session optimizer", args(1,3, arg("",void),arg("sid",int),arg("opt",str))),
     995             :  pattern("clients", "setworkerlimit", CLTsetworkerlimit, false, "", args(1,2, arg("",void),arg("n",int))),
     996             :  pattern("clients", "setworkerlimit", CLTsetworkerlimit, false, "Limit the number of worker threads per query", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
     997             :  pattern("clients", "setmemorylimit", CLTsetmemorylimit, false, "", args(1,2, arg("",void),arg("n",int))),
     998             :  pattern("clients", "setmemorylimit", CLTsetmemorylimit, false, "Limit the memory claim in MB per query", args(1,3, arg("",void),arg("sid",int),arg("n",int))),
     999             :  pattern("clients", "stopsession", CLTstopSession, false, "", args(1,2, arg("",void),arg("sid",bte))),
    1000             :  pattern("clients", "stopsession", CLTstopSession, false, "", args(1,2, arg("",void),arg("sid",sht))),
    1001             :  pattern("clients", "stopsession", CLTstopSession, false, "Stop a particular session", args(1,2, arg("",void),arg("sid",int))),
    1002             :  command("clients", "setprinttimeout", CLTsetPrintTimeout, false, "Print running query every so many seconds.", args(1,2, arg("",void),arg("n",int))),
    1003             :  pattern("clients", "shutdown", CLTshutdown, false, "", args(1,2, arg("",str),arg("delay",int))),
    1004             :  pattern("clients", "shutdown", CLTshutdown, false, "Close all other client connections. Return if it succeeds.\nIf forced is set then always stop the system the hard way", args(1,3, arg("",str),arg("delay",int),arg("forced",bit))),
    1005             :  command("clients", "md5sum", CLTmd5sum, false, "Return hex string representation of the MD5 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1006             :  command("clients", "sha1sum", CLTsha1sum, false, "Return hex string representation of the SHA-1 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1007             :  command("clients", "sha2sum", CLTsha2sum, false, "Return hex string representation of the SHA-2 hash with bits of the given string", args(1,3, arg("",str),arg("pw",str),arg("bits",int))),
    1008             :  command("clients", "ripemd160sum", CLTripemd160sum, false, "Return hex string representation of the RIPEMD160 hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1009             :  command("clients", "backendsum", CLTbackendsum, false, "Return hex string representation of the currently used hash of the given string", args(1,2, arg("",str),arg("pw",str))),
    1010             :  pattern("clients", "addUser", CLTaddUser, false, "Allow user with password access to the given scenarios", args(1,3, arg("",oid),arg("nme",str),arg("pw",str))),
    1011             :  pattern("clients", "removeUser", CLTremoveUser, false, "Remove the given user from the system", args(1,2, arg("",void),arg("nme",str))),
    1012             :  pattern("clients", "getUsername", CLTgetUsername, false, "Return the username of the currently logged in user", args(1,1, arg("",str))),
    1013             :  pattern("clients", "getPasswordHash", CLTgetPasswordHash, false, "Return the password hash of the given user", args(1,2, arg("",str),arg("user",str))),
    1014             :  pattern("clients", "changeUsername", CLTchangeUsername, false, "Change the username of the user into the new string", args(1,3, arg("",void),arg("old",str),arg("new",str))),
    1015             :  pattern("clients", "changePassword", CLTchangePassword, false, "Change the password for the current user", args(1,3, arg("",void),arg("old",str),arg("new",str))),
    1016             :  pattern("clients", "setPassword", CLTsetPassword, false, "Set the password for the given user", args(1,3, arg("",void),arg("user",str),arg("pass",str))),
    1017             :  pattern("clients", "checkPermission", CLTcheckPermission, false, "Check permission for a user, requires hashed password (backendsum)", args(1,3, arg("",void),arg("usr",str),arg("pw",str))),
    1018             :  pattern("clients", "getUsers", CLTgetUsers, false, "return a BAT with user id and one with name available in the system", args(2,2, batarg("",oid),batarg("",str))),
    1019             :  { .imp=NULL }
    1020             : };
    1021             : #include "mal_import.h"
    1022             : #ifdef _MSC_VER
    1023             : #undef read
    1024             : #pragma section(".CRT$XCU",read)
    1025             : #endif
    1026         255 : LIB_STARTUP_FUNC(init_clients_mal)
    1027         255 : { mal_module("clients", NULL, clients_init_funcs); }

Generated by: LCOV version 1.14