server.saveparamslen = 0;
}
-/* I agree, this is a very rudimental way to load a configuration...
- will improve later if the config gets more complex */
-void loadServerConfig(char *filename) {
- FILE *fp;
- char buf[REDIS_CONFIGLINE_MAX+1], *err = NULL;
- int linenum = 0;
- sds line = NULL;
-
- if (filename[0] == '-' && filename[1] == '\0')
- fp = stdin;
- else {
- if ((fp = fopen(filename,"r")) == NULL) {
- redisLog(REDIS_WARNING, "Fatal error, can't open config file '%s'", filename);
- exit(1);
- }
- }
+void loadServerConfigFromString(char *config) {
+ char *err = NULL;
+ int linenum = 0, totlines, i;
+ sds *lines;
+
+ lines = sdssplitlen(config,strlen(config),"\n",1,&totlines);
- while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL) {
+ for (i = 0; i < totlines; i++) {
sds *argv;
- int argc, j;
+ int argc;
- linenum++;
- line = sdsnew(buf);
- line = sdstrim(line," \t\r\n");
+ linenum = i+1;
+ lines[i] = sdstrim(lines[i]," \t\r\n");
/* Skip comments and blank lines*/
- if (line[0] == '#' || line[0] == '\0') {
- sdsfree(line);
- continue;
- }
+ if (lines[i][0] == '#' || lines[i][0] == '\0') continue;
/* Split into arguments */
- argv = sdssplitargs(line,&argc);
+ argv = sdssplitargs(lines[i],&argc);
sdstolower(argv[0]);
/* Execute config directives */
err = "Invalid number of databases"; goto loaderr;
}
} else if (!strcasecmp(argv[0],"include") && argc == 2) {
- loadServerConfig(argv[1]);
+ loadServerConfig(argv[1],NULL);
} else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
server.maxclients = atoi(argv[1]);
} else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
} else {
err = "Bad directive or wrong number of arguments"; goto loaderr;
}
- for (j = 0; j < argc; j++)
- sdsfree(argv[j]);
- zfree(argv);
- sdsfree(line);
+ sdsfreesplitres(argv,argc);
}
- if (fp != stdin) fclose(fp);
+ sdsfreesplitres(lines,totlines);
return;
loaderr:
fprintf(stderr, "\n*** FATAL CONFIG FILE ERROR ***\n");
fprintf(stderr, "Reading the configuration file, at line %d\n", linenum);
- fprintf(stderr, ">>> '%s'\n", line);
+ fprintf(stderr, ">>> '%s'\n", lines[i]);
fprintf(stderr, "%s\n", err);
exit(1);
}
+/* Load the server configuration from the specified filename.
+ * The function appends the additional configuration directives stored
+ * in the 'options' string to the config file before loading.
+ *
+ * Both filename and options can be NULL, in such a case are considered
+ * emtpy. This way loadServerConfig can be used to just load a file or
+ * just load a string. */
+void loadServerConfig(char *filename, char *options) {
+ sds config = sdsempty();
+ char buf[REDIS_CONFIGLINE_MAX+1];
+
+ /* Load the file content */
+ if (filename) {
+ FILE *fp;
+
+ if (filename[0] == '-' && filename[1] == '\0') {
+ fp = stdin;
+ } else {
+ if ((fp = fopen(filename,"r")) == NULL) {
+ redisLog(REDIS_WARNING,
+ "Fatal error, can't open config file '%s'", filename);
+ exit(1);
+ }
+ }
+ while(fgets(buf,REDIS_CONFIGLINE_MAX+1,fp) != NULL)
+ config = sdscat(config,buf);
+ if (fp != stdin) fclose(fp);
+ }
+ /* Append the additional options */
+ if (options) {
+ config = sdscat(config,"\n");
+ config = sdscat(config,options);
+ }
+ loadServerConfigFromString(config);
+ sdsfree(config);
+}
+
/*-----------------------------------------------------------------------------
* CONFIG command for remote configuration
*----------------------------------------------------------------------------*/
zmalloc_enable_thread_safeness();
initServerConfig();
- if (argc == 2) {
+ if (argc >= 2) {
+ int j = 1; /* First option to parse in argv[] */
+ sds options = sdsempty();
+ char *configfile = NULL;
+
+ /* Handle special options --help and --version */
if (strcmp(argv[1], "-v") == 0 ||
strcmp(argv[1], "--version") == 0) version();
if (strcmp(argv[1], "--help") == 0 ||
strcmp(argv[1], "-h") == 0) usage();
+ /* First argument is the config file name? */
+ if (argv[j][0] != '-' || argv[j][1] != '-')
+ configfile = argv[j++];
+ /* All the other options are parsed and conceptually appended to the
+ * configuration file. For instance --port 6380 will generate the
+ * string "port 6380\n" to be parsed after the actual file name
+ * is parsed, if any. */
+ while(j != argc) {
+ if (argv[j][0] == '-' && argv[j][1] == '-') {
+ /* Option name */
+ if (sdslen(options)) options = sdscat(options,"\n");
+ options = sdscat(options,argv[j]+2);
+ options = sdscat(options," ");
+ } else {
+ /* Option argument */
+ options = sdscatrepr(options,argv[j],strlen(argv[j]));
+ options = sdscat(options," ");
+ }
+ j++;
+ }
resetServerSaveParams();
- loadServerConfig(argv[1]);
- } else if ((argc > 2)) {
- usage();
+ loadServerConfig(configfile,options);
+ sdsfree(options);
} else {
redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
}