xref: /redis-3.2.3/src/scripting.c (revision 2f75bbab)
1 #include "redis.h"
2 #include "sha1.h"
3 #include "rand.h"
4 
5 #include <lua.h>
6 #include <lauxlib.h>
7 #include <lualib.h>
8 #include <ctype.h>
9 #include <math.h>
10 
11 char *redisProtocolToLuaType_Int(lua_State *lua, char *reply);
12 char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply);
13 char *redisProtocolToLuaType_Status(lua_State *lua, char *reply);
14 char *redisProtocolToLuaType_Error(lua_State *lua, char *reply);
15 char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply);
16 int redis_math_random (lua_State *L);
17 int redis_math_randomseed (lua_State *L);
18 
19 /* Take a Redis reply in the Redis protocol format and convert it into a
20  * Lua type. Thanks to this function, and the introduction of not connected
21  * clients, it is trvial to implement the redis() lua function.
22  *
23  * Basically we take the arguments, execute the Redis command in the context
24  * of a non connected client, then take the generated reply and convert it
25  * into a suitable Lua type. With this trick the scripting feature does not
26  * need the introduction of a full Redis internals API. Basically the script
27  * is like a normal client that bypasses all the slow I/O paths.
28  *
29  * Note: in this function we do not do any sanity check as the reply is
30  * generated by Redis directly. This allows us to go faster.
31  * The reply string can be altered during the parsing as it is discared
32  * after the conversion is completed.
33  *
34  * Errors are returned as a table with a single 'err' field set to the
35  * error string.
36  */
37 
38 char *redisProtocolToLuaType(lua_State *lua, char* reply) {
39     char *p = reply;
40 
41     switch(*p) {
42     case ':':
43         p = redisProtocolToLuaType_Int(lua,reply);
44         break;
45     case '$':
46         p = redisProtocolToLuaType_Bulk(lua,reply);
47         break;
48     case '+':
49         p = redisProtocolToLuaType_Status(lua,reply);
50         break;
51     case '-':
52         p = redisProtocolToLuaType_Error(lua,reply);
53         break;
54     case '*':
55         p = redisProtocolToLuaType_MultiBulk(lua,reply);
56         break;
57     }
58     return p;
59 }
60 
61 char *redisProtocolToLuaType_Int(lua_State *lua, char *reply) {
62     char *p = strchr(reply+1,'\r');
63     long long value;
64 
65     string2ll(reply+1,p-reply-1,&value);
66     lua_pushnumber(lua,(lua_Number)value);
67     return p+2;
68 }
69 
70 char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply) {
71     char *p = strchr(reply+1,'\r');
72     long long bulklen;
73 
74     string2ll(reply+1,p-reply-1,&bulklen);
75     if (bulklen == -1) {
76         lua_pushboolean(lua,0);
77         return p+2;
78     } else {
79         lua_pushlstring(lua,p+2,bulklen);
80         return p+2+bulklen+2;
81     }
82 }
83 
84 char *redisProtocolToLuaType_Status(lua_State *lua, char *reply) {
85     char *p = strchr(reply+1,'\r');
86 
87     lua_newtable(lua);
88     lua_pushstring(lua,"ok");
89     lua_pushlstring(lua,reply+1,p-reply-1);
90     lua_settable(lua,-3);
91     return p+2;
92 }
93 
94 char *redisProtocolToLuaType_Error(lua_State *lua, char *reply) {
95     char *p = strchr(reply+1,'\r');
96 
97     lua_newtable(lua);
98     lua_pushstring(lua,"err");
99     lua_pushlstring(lua,reply+1,p-reply-1);
100     lua_settable(lua,-3);
101     return p+2;
102 }
103 
104 char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) {
105     char *p = strchr(reply+1,'\r');
106     long long mbulklen;
107     int j = 0;
108 
109     string2ll(reply+1,p-reply-1,&mbulklen);
110     p += 2;
111     if (mbulklen == -1) {
112         lua_pushboolean(lua,0);
113         return p;
114     }
115     lua_newtable(lua);
116     for (j = 0; j < mbulklen; j++) {
117         lua_pushnumber(lua,j+1);
118         p = redisProtocolToLuaType(lua,p);
119         lua_settable(lua,-3);
120     }
121     return p;
122 }
123 
124 void luaPushError(lua_State *lua, char *error) {
125     lua_newtable(lua);
126     lua_pushstring(lua,"err");
127     lua_pushstring(lua, error);
128     lua_settable(lua,-3);
129 }
130 
131 /* Sort the array currently in the stack. We do this to make the output
132  * of commands like KEYS or SMEMBERS something deterministic when called
133  * from Lua (to play well with AOf/replication).
134  *
135  * The array is sorted using table.sort itself, and assuming all the
136  * list elements are strings. */
137 void luaSortArray(lua_State *lua) {
138     /* Initial Stack: array */
139     lua_getglobal(lua,"table");
140     lua_pushstring(lua,"sort");
141     lua_gettable(lua,-2);       /* Stack: array, table, table.sort */
142     lua_pushvalue(lua,-3);      /* Stack: array, table, table.sort, array */
143     if (lua_pcall(lua,1,0,0)) {
144         /* Stack: array, table, error */
145 
146         /* We are not interested in the error, we assume that the problem is
147          * that there are 'false' elements inside the array, so we try
148          * again with a slower function but able to handle this case, that
149          * is: table.sort(table, __redis__compare_helper) */
150         lua_pop(lua,1);             /* Stack: array, table */
151         lua_pushstring(lua,"sort"); /* Stack: array, table, sort */
152         lua_gettable(lua,-2);       /* Stack: array, table, table.sort */
153         lua_pushvalue(lua,-3);      /* Stack: array, table, table.sort, array */
154         lua_getglobal(lua,"__redis__compare_helper");
155         /* Stack: array, table, table.sort, array, __redis__compare_helper */
156         lua_call(lua,2,0);
157     }
158     /* Stack: array (sorted), table */
159     lua_pop(lua,1);             /* Stack: array (sorted) */
160 }
161 
162 int luaRedisGenericCommand(lua_State *lua, int raise_error) {
163     int j, argc = lua_gettop(lua);
164     struct redisCommand *cmd;
165     robj **argv;
166     redisClient *c = server.lua_client;
167     sds reply;
168 
169     /* Build the arguments vector */
170     argv = zmalloc(sizeof(robj*)*argc);
171     for (j = 0; j < argc; j++) {
172         if (!lua_isstring(lua,j+1)) break;
173         argv[j] = createStringObject((char*)lua_tostring(lua,j+1),
174                                      lua_strlen(lua,j+1));
175     }
176 
177     /* Check if one of the arguments passed by the Lua script
178      * is not a string or an integer (lua_isstring() return true for
179      * integers as well). */
180     if (j != argc) {
181         j--;
182         while (j >= 0) {
183             decrRefCount(argv[j]);
184             j--;
185         }
186         zfree(argv);
187         luaPushError(lua,
188             "Lua redis() command arguments must be strings or integers");
189         return 1;
190     }
191 
192     /* Setup our fake client for command execution */
193     c->argv = argv;
194     c->argc = argc;
195 
196     /* Command lookup */
197     cmd = lookupCommand(argv[0]->ptr);
198     if (!cmd || ((cmd->arity > 0 && cmd->arity != argc) ||
199                    (argc < -cmd->arity)))
200     {
201         if (cmd)
202             luaPushError(lua,
203                 "Wrong number of args calling Redis command From Lua script");
204         else
205             luaPushError(lua,"Unknown Redis command called from Lua script");
206         goto cleanup;
207     }
208 
209     if (cmd->flags & REDIS_CMD_NOSCRIPT) {
210         luaPushError(lua, "This Redis command is not allowed from scripts");
211         goto cleanup;
212     }
213 
214     if (cmd->flags & REDIS_CMD_WRITE && server.lua_random_dirty) {
215         luaPushError(lua,
216             "Write commands not allowed after non deterministic commands");
217         goto cleanup;
218     }
219 
220     if (cmd->flags & REDIS_CMD_RANDOM) server.lua_random_dirty = 1;
221     if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1;
222 
223     /* Run the command */
224     c->cmd = cmd;
225     call(c,REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
226 
227     /* Convert the result of the Redis command into a suitable Lua type.
228      * The first thing we need is to create a single string from the client
229      * output buffers. */
230     reply = sdsempty();
231     if (c->bufpos) {
232         reply = sdscatlen(reply,c->buf,c->bufpos);
233         c->bufpos = 0;
234     }
235     while(listLength(c->reply)) {
236         robj *o = listNodeValue(listFirst(c->reply));
237 
238         reply = sdscatlen(reply,o->ptr,sdslen(o->ptr));
239         listDelNode(c->reply,listFirst(c->reply));
240     }
241     if (raise_error && reply[0] != '-') raise_error = 0;
242     redisProtocolToLuaType(lua,reply);
243     /* Sort the output array if needed, assuming it is a non-null multi bulk
244      * reply as expected. */
245     if ((cmd->flags & REDIS_CMD_SORT_FOR_SCRIPT) &&
246         (reply[0] == '*' && reply[1] != '-')) {
247         /* Skip this step if command is SORT but output was already sorted */
248         if (cmd->proc != sortCommand || server.sort_dontsort)
249             luaSortArray(lua);
250     }
251     sdsfree(reply);
252 
253 cleanup:
254     /* Clean up. Command code may have changed argv/argc so we use the
255      * argv/argc of the client instead of the local variables. */
256     for (j = 0; j < c->argc; j++)
257         decrRefCount(c->argv[j]);
258     zfree(c->argv);
259 
260     if (raise_error) {
261         /* If we are here we should have an error in the stack, in the
262          * form of a table with an "err" field. Extract the string to
263          * return the plain error. */
264         lua_pushstring(lua,"err");
265         lua_gettable(lua,-2);
266         return lua_error(lua);
267     }
268     return 1;
269 }
270 
271 int luaRedisCallCommand(lua_State *lua) {
272     return luaRedisGenericCommand(lua,1);
273 }
274 
275 int luaRedisPCallCommand(lua_State *lua) {
276     return luaRedisGenericCommand(lua,0);
277 }
278 
279 int luaLogCommand(lua_State *lua) {
280     int j, argc = lua_gettop(lua);
281     int level;
282     sds log;
283 
284     if (argc < 2) {
285         luaPushError(lua, "redis.log() requires two arguments or more.");
286         return 1;
287     } else if (!lua_isnumber(lua,-argc)) {
288         luaPushError(lua, "First argument must be a number (log level).");
289         return 1;
290     }
291     level = lua_tonumber(lua,-argc);
292     if (level < REDIS_DEBUG || level > REDIS_WARNING) {
293         luaPushError(lua, "Invalid debug level.");
294         return 1;
295     }
296 
297     /* Glue together all the arguments */
298     log = sdsempty();
299     for (j = 1; j < argc; j++) {
300         size_t len;
301         char *s;
302 
303         s = (char*)lua_tolstring(lua,(-argc)+j,&len);
304         if (s) {
305             if (j != 1) log = sdscatlen(log," ",1);
306             log = sdscatlen(log,s,len);
307         }
308     }
309     redisLogRaw(level,log);
310     sdsfree(log);
311     return 0;
312 }
313 
314 void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
315     long long elapsed;
316     REDIS_NOTUSED(ar);
317     REDIS_NOTUSED(lua);
318 
319     elapsed = (ustime()/1000) - server.lua_time_start;
320     if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
321         redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
322         server.lua_timedout = 1;
323         /* Once the script timeouts we reenter the event loop to permit others
324          * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
325          * we need to mask the client executing the script from the event loop.
326          * If we don't do that the client may disconnect and could no longer be
327          * here when the EVAL command will return. */
328          aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE);
329     }
330     if (server.lua_timedout)
331         aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT);
332     if (server.lua_kill) {
333         redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL.");
334         lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
335         lua_error(lua);
336     }
337 }
338 
339 void luaLoadLib(lua_State *lua, const char *libname, lua_CFunction luafunc) {
340   lua_pushcfunction(lua, luafunc);
341   lua_pushstring(lua, libname);
342   lua_call(lua, 1, 0);
343 }
344 
345 LUALIB_API int (luaopen_cjson) (lua_State *L);
346 LUALIB_API int (luaopen_struct) (lua_State *L);
347 
348 void luaLoadLibraries(lua_State *lua) {
349     luaLoadLib(lua, "", luaopen_base);
350     luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);
351     luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);
352     luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);
353     luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug);
354     luaLoadLib(lua, "cjson", luaopen_cjson);
355     luaLoadLib(lua, "struct", luaopen_struct);
356 
357 #if 0 /* Stuff that we don't load currently, for sandboxing concerns. */
358     luaLoadLib(lua, LUA_LOADLIBNAME, luaopen_package);
359     luaLoadLib(lua, LUA_OSLIBNAME, luaopen_os);
360 #endif
361 }
362 
363 /* Initialize the scripting environment.
364  * It is possible to call this function to reset the scripting environment
365  * assuming that we call scriptingRelease() before.
366  * See scriptingReset() for more information. */
367 void scriptingInit(void) {
368     lua_State *lua = lua_open();
369     luaLoadLibraries(lua);
370 
371     /* Initialize a dictionary we use to map SHAs to scripts.
372      * This is useful for replication, as we need to replicate EVALSHA
373      * as EVAL, so we need to remember the associated script. */
374     server.lua_scripts = dictCreate(&dbDictType,NULL);
375 
376     /* Register the redis commands table and fields */
377     lua_newtable(lua);
378 
379     /* redis.call */
380     lua_pushstring(lua,"call");
381     lua_pushcfunction(lua,luaRedisCallCommand);
382     lua_settable(lua,-3);
383 
384     /* redis.pcall */
385     lua_pushstring(lua,"pcall");
386     lua_pushcfunction(lua,luaRedisPCallCommand);
387     lua_settable(lua,-3);
388 
389     /* redis.log and log levels. */
390     lua_pushstring(lua,"log");
391     lua_pushcfunction(lua,luaLogCommand);
392     lua_settable(lua,-3);
393 
394     lua_pushstring(lua,"LOG_DEBUG");
395     lua_pushnumber(lua,REDIS_DEBUG);
396     lua_settable(lua,-3);
397 
398     lua_pushstring(lua,"LOG_VERBOSE");
399     lua_pushnumber(lua,REDIS_VERBOSE);
400     lua_settable(lua,-3);
401 
402     lua_pushstring(lua,"LOG_NOTICE");
403     lua_pushnumber(lua,REDIS_NOTICE);
404     lua_settable(lua,-3);
405 
406     lua_pushstring(lua,"LOG_WARNING");
407     lua_pushnumber(lua,REDIS_WARNING);
408     lua_settable(lua,-3);
409 
410     /* Finally set the table as 'redis' global var. */
411     lua_setglobal(lua,"redis");
412 
413     /* Replace math.random and math.randomseed with our implementations. */
414     lua_getglobal(lua,"math");
415 
416     lua_pushstring(lua,"random");
417     lua_pushcfunction(lua,redis_math_random);
418     lua_settable(lua,-3);
419 
420     lua_pushstring(lua,"randomseed");
421     lua_pushcfunction(lua,redis_math_randomseed);
422     lua_settable(lua,-3);
423 
424     lua_setglobal(lua,"math");
425 
426     /* Add a helper funciton that we use to sort the multi bulk output of non
427      * deterministic commands, when containing 'false' elements. */
428     {
429         char *compare_func =    "function __redis__compare_helper(a,b)\n"
430                                 "  if a == false then a = '' end\n"
431                                 "  if b == false then b = '' end\n"
432                                 "  return a<b\n"
433                                 "end\n";
434         luaL_loadbuffer(lua,compare_func,strlen(compare_func),"cmp_func_def");
435         lua_pcall(lua,0,0,0);
436     }
437 
438     /* Create the (non connected) client that we use to execute Redis commands
439      * inside the Lua interpreter.
440      * Note: there is no need to create it again when this function is called
441      * by scriptingReset(). */
442     if (server.lua_client == NULL) {
443         server.lua_client = createClient(-1);
444         server.lua_client->flags |= REDIS_LUA_CLIENT;
445     }
446 
447     server.lua = lua;
448 }
449 
450 /* Release resources related to Lua scripting.
451  * This function is used in order to reset the scripting environment. */
452 void scriptingRelease(void) {
453     dictRelease(server.lua_scripts);
454     lua_close(server.lua);
455 }
456 
457 void scriptingReset(void) {
458     scriptingRelease();
459     scriptingInit();
460 }
461 
462 /* Hash the scripit into a SHA1 digest. We use this as Lua function name.
463  * Digest should point to a 41 bytes buffer: 40 for SHA1 converted into an
464  * hexadecimal number, plus 1 byte for null term. */
465 void hashScript(char *digest, char *script, size_t len) {
466     SHA1_CTX ctx;
467     unsigned char hash[20];
468     char *cset = "0123456789abcdef";
469     int j;
470 
471     SHA1Init(&ctx);
472     SHA1Update(&ctx,(unsigned char*)script,len);
473     SHA1Final(hash,&ctx);
474 
475     for (j = 0; j < 20; j++) {
476         digest[j*2] = cset[((hash[j]&0xF0)>>4)];
477         digest[j*2+1] = cset[(hash[j]&0xF)];
478     }
479     digest[40] = '\0';
480 }
481 
482 void luaReplyToRedisReply(redisClient *c, lua_State *lua) {
483     int t = lua_type(lua,-1);
484 
485     switch(t) {
486     case LUA_TSTRING:
487         addReplyBulkCBuffer(c,(char*)lua_tostring(lua,-1),lua_strlen(lua,-1));
488         break;
489     case LUA_TBOOLEAN:
490         addReply(c,lua_toboolean(lua,-1) ? shared.cone : shared.nullbulk);
491         break;
492     case LUA_TNUMBER:
493         addReplyLongLong(c,(long long)lua_tonumber(lua,-1));
494         break;
495     case LUA_TTABLE:
496         /* We need to check if it is an array, an error, or a status reply.
497          * Error are returned as a single element table with 'err' field.
498          * Status replies are returned as single elment table with 'ok' field */
499         lua_pushstring(lua,"err");
500         lua_gettable(lua,-2);
501         t = lua_type(lua,-1);
502         if (t == LUA_TSTRING) {
503             sds err = sdsnew(lua_tostring(lua,-1));
504             sdsmapchars(err,"\r\n","  ",2);
505             addReplySds(c,sdscatprintf(sdsempty(),"-%s\r\n",err));
506             sdsfree(err);
507             lua_pop(lua,2);
508             return;
509         }
510 
511         lua_pop(lua,1);
512         lua_pushstring(lua,"ok");
513         lua_gettable(lua,-2);
514         t = lua_type(lua,-1);
515         if (t == LUA_TSTRING) {
516             sds ok = sdsnew(lua_tostring(lua,-1));
517             sdsmapchars(ok,"\r\n","  ",2);
518             addReplySds(c,sdscatprintf(sdsempty(),"+%s\r\n",ok));
519             sdsfree(ok);
520             lua_pop(lua,1);
521         } else {
522             void *replylen = addDeferredMultiBulkLength(c);
523             int j = 1, mbulklen = 0;
524 
525             lua_pop(lua,1); /* Discard the 'ok' field value we popped */
526             while(1) {
527                 lua_pushnumber(lua,j++);
528                 lua_gettable(lua,-2);
529                 t = lua_type(lua,-1);
530                 if (t == LUA_TNIL) {
531                     lua_pop(lua,1);
532                     break;
533                 }
534                 luaReplyToRedisReply(c, lua);
535                 mbulklen++;
536             }
537             setDeferredMultiBulkLength(c,replylen,mbulklen);
538         }
539         break;
540     default:
541         addReply(c,shared.nullbulk);
542     }
543     lua_pop(lua,1);
544 }
545 
546 /* Set an array of Redis String Objects as a Lua array (table) stored into a
547  * global variable. */
548 void luaSetGlobalArray(lua_State *lua, char *var, robj **elev, int elec) {
549     int j;
550 
551     lua_newtable(lua);
552     for (j = 0; j < elec; j++) {
553         lua_pushlstring(lua,(char*)elev[j]->ptr,sdslen(elev[j]->ptr));
554         lua_rawseti(lua,-2,j+1);
555     }
556     lua_setglobal(lua,var);
557 }
558 
559 /* Define a lua function with the specified function name and body.
560  * The function name musts be a 2 characters long string, since all the
561  * functions we defined in the Lua context are in the form:
562  *
563  *   f_<hex sha1 sum>
564  *
565  * On success REDIS_OK is returned, and nothing is left on the Lua stack.
566  * On error REDIS_ERR is returned and an appropriate error is set in the
567  * client context. */
568 int luaCreateFunction(redisClient *c, lua_State *lua, char *funcname, robj *body) {
569     sds funcdef = sdsempty();
570 
571     funcdef = sdscat(funcdef,"function ");
572     funcdef = sdscatlen(funcdef,funcname,42);
573     funcdef = sdscatlen(funcdef,"() ",3);
574     funcdef = sdscatlen(funcdef,body->ptr,sdslen(body->ptr));
575     funcdef = sdscatlen(funcdef," end",4);
576 
577     if (luaL_loadbuffer(lua,funcdef,sdslen(funcdef),"func definition")) {
578         addReplyErrorFormat(c,"Error compiling script (new function): %s\n",
579             lua_tostring(lua,-1));
580         lua_pop(lua,1);
581         sdsfree(funcdef);
582         return REDIS_ERR;
583     }
584     sdsfree(funcdef);
585     if (lua_pcall(lua,0,0,0)) {
586         addReplyErrorFormat(c,"Error running script (new function): %s\n",
587             lua_tostring(lua,-1));
588         lua_pop(lua,1);
589         return REDIS_ERR;
590     }
591 
592     /* We also save a SHA1 -> Original script map in a dictionary
593      * so that we can replicate / write in the AOF all the
594      * EVALSHA commands as EVAL using the original script. */
595     {
596         int retval = dictAdd(server.lua_scripts,
597                              sdsnewlen(funcname+2,40),body);
598         redisAssertWithInfo(c,NULL,retval == DICT_OK);
599         incrRefCount(body);
600     }
601     return REDIS_OK;
602 }
603 
604 void evalGenericCommand(redisClient *c, int evalsha) {
605     lua_State *lua = server.lua;
606     char funcname[43];
607     long long numkeys;
608 
609     /* We want the same PRNG sequence at every call so that our PRNG is
610      * not affected by external state. */
611     redisSrand48(0);
612 
613     /* We set this flag to zero to remember that so far no random command
614      * was called. This way we can allow the user to call commands like
615      * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
616      * is called (otherwise the replication and AOF would end with non
617      * deterministic sequences).
618      *
619      * Thanks to this flag we'll raise an error every time a write command
620      * is called after a random command was used. */
621     server.lua_random_dirty = 0;
622     server.lua_write_dirty = 0;
623 
624     /* Get the number of arguments that are keys */
625     if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
626         return;
627     if (numkeys > (c->argc - 3)) {
628         addReplyError(c,"Number of keys can't be greater than number of args");
629         return;
630     }
631 
632     /* We obtain the script SHA1, then check if this function is already
633      * defined into the Lua state */
634     funcname[0] = 'f';
635     funcname[1] = '_';
636     if (!evalsha) {
637         /* Hash the code if this is an EVAL call */
638         hashScript(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
639     } else {
640         /* We already have the SHA if it is a EVALSHA */
641         int j;
642         char *sha = c->argv[1]->ptr;
643 
644         for (j = 0; j < 40; j++)
645             funcname[j+2] = tolower(sha[j]);
646         funcname[42] = '\0';
647     }
648 
649     /* Try to lookup the Lua function */
650     lua_getglobal(lua, funcname);
651     if (lua_isnil(lua,1)) {
652         lua_pop(lua,1); /* remove the nil from the stack */
653         /* Function not defined... let's define it if we have the
654          * body of the funciton. If this is an EVALSHA call we can just
655          * return an error. */
656         if (evalsha) {
657             addReply(c, shared.noscripterr);
658             return;
659         }
660         if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
661         /* Now the following is guaranteed to return non nil */
662         lua_getglobal(lua, funcname);
663         redisAssert(!lua_isnil(lua,1));
664     }
665 
666     /* Populate the argv and keys table accordingly to the arguments that
667      * EVAL received. */
668     luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
669     luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);
670 
671     /* Select the right DB in the context of the Lua client */
672     selectDb(server.lua_client,c->db->id);
673 
674     /* Set an hook in order to be able to stop the script execution if it
675      * is running for too much time.
676      * We set the hook only if the time limit is enabled as the hook will
677      * make the Lua script execution slower. */
678     if (server.lua_time_limit > 0 && server.masterhost == NULL) {
679         lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
680     } else {
681         lua_sethook(lua,luaMaskCountHook,0,0);
682     }
683 
684     /* At this point whatever this script was never seen before or if it was
685      * already defined, we can call it. We have zero arguments and expect
686      * a single return value. */
687     server.lua_caller = c;
688     server.lua_time_start = ustime()/1000;
689     server.lua_kill = 0;
690     if (lua_pcall(lua,0,1,0)) {
691         if (server.lua_timedout) {
692             server.lua_timedout = 0;
693             /* Restore the readable handler that was unregistered when the
694              * script timeout was detected. */
695             aeCreateFileEvent(server.el,c->fd,AE_READABLE,
696                               readQueryFromClient,c);
697         }
698         server.lua_caller = NULL;
699         selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
700         addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
701             funcname, lua_tostring(lua,-1));
702         lua_pop(lua,1);
703         lua_gc(lua,LUA_GCCOLLECT,0);
704         return;
705     }
706     server.lua_timedout = 0;
707     server.lua_caller = NULL;
708     selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
709     luaReplyToRedisReply(c,lua);
710     lua_gc(lua,LUA_GCSTEP,1);
711 
712     /* If we have slaves attached we want to replicate this command as
713      * EVAL instead of EVALSHA. We do this also in the AOF as currently there
714      * is no easy way to propagate a command in a different way in the AOF
715      * and in the replication link.
716      *
717      * IMPROVEMENT POSSIBLE:
718      * 1) Replicate this command as EVALSHA in the AOF.
719      * 2) Remember what slave already received a given script, and replicate
720      *    the EVALSHA against this slaves when possible.
721      */
722     if (evalsha) {
723         robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);
724 
725         redisAssertWithInfo(c,NULL,script != NULL);
726         rewriteClientCommandArgument(c,0,
727             resetRefCount(createStringObject("EVAL",4)));
728         rewriteClientCommandArgument(c,1,script);
729     }
730 }
731 
732 void evalCommand(redisClient *c) {
733     evalGenericCommand(c,0);
734 }
735 
736 void evalShaCommand(redisClient *c) {
737     if (sdslen(c->argv[1]->ptr) != 40) {
738         /* We know that a match is not possible if the provided SHA is
739          * not the right length. So we return an error ASAP, this way
740          * evalGenericCommand() can be implemented without string length
741          * sanity check */
742         addReply(c, shared.noscripterr);
743         return;
744     }
745     evalGenericCommand(c,1);
746 }
747 
748 /* We replace math.random() with our implementation that is not affected
749  * by specific libc random() implementations and will output the same sequence
750  * (for the same seed) in every arch. */
751 
752 /* The following implementation is the one shipped with Lua itself but with
753  * rand() replaced by redisLrand48(). */
754 int redis_math_random (lua_State *L) {
755   /* the `%' avoids the (rare) case of r==1, and is needed also because on
756      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
757   lua_Number r = (lua_Number)(redisLrand48()%REDIS_LRAND48_MAX) /
758                                 (lua_Number)REDIS_LRAND48_MAX;
759   switch (lua_gettop(L)) {  /* check number of arguments */
760     case 0: {  /* no arguments */
761       lua_pushnumber(L, r);  /* Number between 0 and 1 */
762       break;
763     }
764     case 1: {  /* only upper limit */
765       int u = luaL_checkint(L, 1);
766       luaL_argcheck(L, 1<=u, 1, "interval is empty");
767       lua_pushnumber(L, floor(r*u)+1);  /* int between 1 and `u' */
768       break;
769     }
770     case 2: {  /* lower and upper limits */
771       int l = luaL_checkint(L, 1);
772       int u = luaL_checkint(L, 2);
773       luaL_argcheck(L, l<=u, 2, "interval is empty");
774       lua_pushnumber(L, floor(r*(u-l+1))+l);  /* int between `l' and `u' */
775       break;
776     }
777     default: return luaL_error(L, "wrong number of arguments");
778   }
779   return 1;
780 }
781 
782 int redis_math_randomseed (lua_State *L) {
783   redisSrand48(luaL_checkint(L, 1));
784   return 0;
785 }
786 
787 /* ---------------------------------------------------------------------------
788  * SCRIPT command for script environment introspection and control
789  * ------------------------------------------------------------------------- */
790 
791 void scriptCommand(redisClient *c) {
792     if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
793         scriptingReset();
794         addReply(c,shared.ok);
795         server.dirty++; /* Replicating this command is a good idea. */
796     } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
797         int j;
798 
799         addReplyMultiBulkLen(c, c->argc-2);
800         for (j = 2; j < c->argc; j++) {
801             if (dictFind(server.lua_scripts,c->argv[j]->ptr))
802                 addReply(c,shared.cone);
803             else
804                 addReply(c,shared.czero);
805         }
806     } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr,"load")) {
807         char funcname[43];
808         sds sha;
809 
810         funcname[0] = 'f';
811         funcname[1] = '_';
812         hashScript(funcname+2,c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
813         sha = sdsnewlen(funcname+2,40);
814         if (dictFind(server.lua_scripts,sha) == NULL) {
815             if (luaCreateFunction(c,server.lua,funcname,c->argv[2])
816                     == REDIS_ERR) {
817                 sdsfree(sha);
818                 return;
819             }
820         }
821         addReplyBulkCBuffer(c,funcname+2,40);
822         sdsfree(sha);
823     } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
824         if (server.lua_caller == NULL) {
825             addReplyError(c,"No scripts in execution right now.");
826         } else if (server.lua_write_dirty) {
827             addReplyError(c, "Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in an hard way using the SHUTDOWN NOSAVE command.");
828         } else {
829             server.lua_kill = 1;
830             addReply(c,shared.ok);
831         }
832     } else {
833         addReplyError(c, "Unknown SCRIPT subcommand or wrong # of args.");
834     }
835 }
836