aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authoronefang2020-03-17 20:52:32 +1000
committeronefang2020-03-17 20:52:32 +1000
commitcaef5b34f9e94a0375d3a8e8b5fb4040b3a0406a (patch)
tree2ac87bc0e8e0432d9ba765122a2e4c1f52e940e4
parentAdd an About me textarea. (diff)
downloadopensim-SC_OLD-caef5b34f9e94a0375d3a8e8b5fb4040b3a0406a.zip
opensim-SC_OLD-caef5b34f9e94a0375d3a8e8b5fb4040b3a0406a.tar.gz
opensim-SC_OLD-caef5b34f9e94a0375d3a8e8b5fb4040b3a0406a.tar.bz2
opensim-SC_OLD-caef5b34f9e94a0375d3a8e8b5fb4040b3a0406a.tar.xz
Switch to using FHS style directories, and create them all at startup.
-rw-r--r--src/.sledjChisl.conf.lua4
-rw-r--r--src/sledjchisl/sledjchisl.c127
2 files changed, 91 insertions, 40 deletions
diff --git a/src/.sledjChisl.conf.lua b/src/.sledjChisl.conf.lua
index bc04835..f7289de 100644
--- a/src/.sledjChisl.conf.lua
+++ b/src/.sledjChisl.conf.lua
@@ -12,11 +12,11 @@ config =
12 ["scRoot"] = "/opt/opensim_SC"; 12 ["scRoot"] = "/opt/opensim_SC";
13 ["scUser"] = "opensimsc"; 13 ["scUser"] = "opensimsc";
14 ["Tconsole"] = "SledjChisl"; 14 ["Tconsole"] = "SledjChisl";
15 ["Tsocket"] = "caches/opensim-tmux.socket"; 15 ["Tsocket"] = "opensim-tmux.socket";
16 ["Ttab"] = "SC"; 16 ["Ttab"] = "SC";
17 ["loadAverageInc"] = 0.7; 17 ["loadAverageInc"] = 0.7;
18 ["simTimeOut"] = 45; -- seconds 18 ["simTimeOut"] = 45; -- seconds
19 ["webRoot"] = "/var/www"; 19 ["webRoot"] = "/var/www/html";
20 ["URL"] = "sledjchisl.fcgi"; 20 ["URL"] = "sledjchisl.fcgi";
21 ["seshTimeOut"] = 30 * 60; -- seconds 21 ["seshTimeOut"] = 30 * 60; -- seconds
22 ["idleTimeOut"] = 24 * 60 * 60; -- seconds 22 ["idleTimeOut"] = 24 * 60 * 60; -- seconds
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c
index 9808245..60102f3 100644
--- a/src/sledjchisl/sledjchisl.c
+++ b/src/sledjchisl/sledjchisl.c
@@ -20,24 +20,6 @@ config SLEDJCHISL
20 20
21// TODO - do all the setup on first run, and check if needed on each start up, to be self healing. 21// TODO - do all the setup on first run, and check if needed on each start up, to be self healing.
22 22
23// TODO - create any missing directories when we need them.
24
25// TODO - use a FHS compatible setup -
26// scRoot = / /usr/local /opt/opensim_SC
27// /etc/opensim_SC /usr/local/etc/opensim_SC /opt/opensim_SC/etc
28// /run/opensim_SC /run/opensim_SC /run/opensim_SC
29// /usr/bin /usr/local/bin /opt/opensim_SC/bin
30// The problem here is that OpenSim already uses opensim/bin for all of it's crap, where they mix it all together.
31// Don't want it in the path.
32// Should put the .dlls into ../lib..
33// Most of the rest is config files or common assets.
34// /usr/lib/opensim_SC /usr/local/lib/opensim_SC /opt/opensim_SC/lib
35// /var/backups/opensim_SC /var/local/backups/opensim_SC /opt/opensim_SC/var/backups
36// /var/cache/opensim_SC /var/local/cache/opensim_SC /opt/opensim_SC/var/cache
37// /var/lib/opensim_SC /var/local/lib/opensim_SC /opt/opensim_SC/var/lib
38// /var/log/opensim_SC /var/local/log/opensim_SC /opt/opensim_SC/var/log
39// /var/www/opensim_SC /var/local/www/opensim_SC /opt/opensim_SC/var/www
40
41// TODO - pepper could be entered on the console on startup if it's not defined, as a master password sort of thing. 23// TODO - pepper could be entered on the console on startup if it's not defined, as a master password sort of thing.
42// I'd go as far as protecting the database credentials that way, but legacy OpenSim needs it unprotected. 24// I'd go as far as protecting the database credentials that way, but legacy OpenSim needs it unprotected.
43// Also keep in mind, people want autostart of their services without having to enter passwords on each boot. 25// Also keep in mind, people want autostart of their services without having to enter passwords on each boot.
@@ -456,11 +438,19 @@ boolean isWeb = 0;
456char *pwd = ""; 438char *pwd = "";
457char *scRoot = "/opt/opensim_SC"; 439char *scRoot = "/opt/opensim_SC";
458char *scUser = "opensimsc"; 440char *scUser = "opensimsc";
441char *scBin = "";
442char *scEtc = "";
443char *scLib = "";
444char *scRun = "";
445char *scBackup = "";
446char *scCache = "";
447char *scData = "";
448char *scLog = "";
459char *Tconsole = "SledjChisl"; 449char *Tconsole = "SledjChisl";
460char *Tsocket = "caches/opensim-tmux.socket"; 450char *Tsocket = "opensim-tmux.socket";
461char *Ttab = "SC"; 451char *Ttab = "SC";
462char *Tcmd = "tmux -S"; 452char *Tcmd = "tmux -S";
463char *webRoot = "/opt/opensim_SC/web"; 453char *webRoot = "/var/www/html";
464char *URL = "fcgi-bin/sledjchisl.fcgi"; 454char *URL = "fcgi-bin/sledjchisl.fcgi";
465char *ToS = "Be good."; 455char *ToS = "Be good.";
466int seshTimeOut = 30 * 60; 456int seshTimeOut = 30 * 60;
@@ -592,7 +582,7 @@ void PrintTable(lua_State *L)
592int sendTmuxKeys(char *dest, char *keys) 582int sendTmuxKeys(char *dest, char *keys)
593{ 583{
594 int ret = 0, i; 584 int ret = 0, i;
595 char *c = xmprintf("%s %s/%s send-keys -t %s:%s '%s'", Tcmd, scRoot, Tsocket, Tconsole, dest, keys); 585 char *c = xmprintf("%s %s/%s send-keys -t %s:%s '%s'", Tcmd, scRun, Tsocket, Tconsole, dest, keys);
596 586
597 i = system(c); 587 i = system(c);
598 if (!WIFEXITED(i)) 588 if (!WIFEXITED(i))
@@ -604,7 +594,7 @@ int sendTmuxKeys(char *dest, char *keys)
604int sendTmuxCmd(char *dest, char *cmd) 594int sendTmuxCmd(char *dest, char *cmd)
605{ 595{
606 int ret = 0, i; 596 int ret = 0, i;
607 char *c = xmprintf("%s %s/%s send-keys -t %s:'%s' '%s' Enter", Tcmd, scRoot, Tsocket, Tconsole, dest, cmd); 597 char *c = xmprintf("%s %s/%s send-keys -t %s:'%s' '%s' Enter", Tcmd, scRun, Tsocket, Tconsole, dest, cmd);
608 598
609 i = system(c); 599 i = system(c);
610 if (!WIFEXITED(i)) 600 if (!WIFEXITED(i))
@@ -616,7 +606,7 @@ int sendTmuxCmd(char *dest, char *cmd)
616void waitTmuxText(char *dest, char *text) 606void waitTmuxText(char *dest, char *text)
617{ 607{
618 int i; 608 int i;
619 char *c = xmprintf("sleep 5; %s %s/%s capture-pane -t %s:'%s' -p | grep -E '%s' 2>&1 > /dev/null", Tcmd, scRoot, Tsocket, Tconsole, dest, text); 609 char *c = xmprintf("sleep 5; %s %s/%s capture-pane -t %s:'%s' -p | grep -E '%s' 2>&1 > /dev/null", Tcmd, scRun, Tsocket, Tconsole, dest, text);
620 610
621 D("Waiting for '%s'.", text); 611 D("Waiting for '%s'.", text);
622 do 612 do
@@ -2725,10 +2715,10 @@ static void freeSesh(reqData *Rd, boolean linky, boolean wipe)
2725 if (linky) 2715 if (linky)
2726 { 2716 {
2727 shs = Rd->lnk; 2717 shs = Rd->lnk;
2728 file = xmprintf("%s/caches/sessions/%s.linky", getStrH(Rd->configs, "scRoot"), shs->leaf); 2718 file = xmprintf("%s/sessions/%s.linky", scCache, shs->leaf);
2729 } 2719 }
2730 else 2720 else
2731 file = xmprintf("%s/caches/sessions/%s.lua", getStrH(Rd->configs, "scRoot"), shs->leaf); 2721 file = xmprintf("%s/sessions/%s.lua", scCache, shs->leaf);
2732 2722
2733 if (wipe) 2723 if (wipe)
2734 I("Wiping session %s.", file); 2724 I("Wiping session %s.", file);
@@ -2784,11 +2774,11 @@ static void setToken_n_munchie(reqData *Rd, boolean linky)
2784 if (linky) 2774 if (linky)
2785 { 2775 {
2786 shs = Rd->lnk; 2776 shs = Rd->lnk;
2787 file = xmprintf("%s/caches/sessions/%s.linky", getStrH(Rd->configs, "scRoot"), shs->leaf); 2777 file = xmprintf("%s/sessions/%s.linky", scCache, shs->leaf);
2788 } 2778 }
2789 else 2779 else
2790 { 2780 {
2791 file = xmprintf("%s/caches/sessions/%s.lua", getStrH(Rd->configs, "scRoot"), shs->leaf); 2781 file = xmprintf("%s/sessions/%s.lua", scCache, shs->leaf);
2792 if (NULL != Rd->lnk) 2782 if (NULL != Rd->lnk)
2793 link = Rd->lnk->hashish; 2783 link = Rd->lnk->hashish;
2794 } 2784 }
@@ -2844,7 +2834,7 @@ static void setToken_n_munchie(reqData *Rd, boolean linky)
2844 2834
2845static void createUser(reqData *Rd) 2835static void createUser(reqData *Rd)
2846{ 2836{
2847 char *file = xmprintf("%s/var/lib/users/%s.lua", getStrH(Rd->configs, "scRoot"), getStrH(Rd->stuff, "UUID")); 2837 char *file = xmprintf("%s/users/%s.lua", scData, getStrH(Rd->stuff, "UUID"));
2848 char *tnm = xmprintf( "user = \n" 2838 char *tnm = xmprintf( "user = \n"
2849 "{\n" 2839 "{\n"
2850 " ['name']='%s',\n" 2840 " ['name']='%s',\n"
@@ -2898,7 +2888,7 @@ static void createUser(reqData *Rd)
2898 else 2888 else
2899 { 2889 {
2900 char *name = Rd->stuff->getstr(Rd->stuff, "name", true); 2890 char *name = Rd->stuff->getstr(Rd->stuff, "name", true);
2901 char *nm = xmprintf("%s/var/lib/users/%s.lua", getStrH(Rd->configs, "scRoot"), qstrreplace("tr", name, " ", "_")); 2891 char *nm = xmprintf("%s/users/%s.lua", scData, qstrreplace("tr", name, " ", "_"));
2902 2892
2903 free(file); 2893 free(file);
2904 file = xmprintf("%s.lua", getStrH(Rd->stuff, "UUID")); 2894 file = xmprintf("%s.lua", getStrH(Rd->stuff, "UUID"));
@@ -3180,9 +3170,9 @@ static int validateSesh(reqData *Rd, qhashtbl_t *data)
3180 leaf = myHMACkey(getStrH(Rd->configs, "pepper"), hashish, TRUE); 3170 leaf = myHMACkey(getStrH(Rd->configs, "pepper"), hashish, TRUE);
3181//D("leaf %s", leaf); 3171//D("leaf %s", leaf);
3182 if (linky) 3172 if (linky)
3183 t0 = xmprintf("%s/caches/sessions/%s.linky", getStrH(Rd->configs, "scRoot"), leaf); 3173 t0 = xmprintf("%s/sessions/%s.linky", scCache, leaf);
3184 else 3174 else
3185 t0 = xmprintf("%s/caches/sessions/%s.lua", getStrH(Rd->configs, "scRoot"), leaf); 3175 t0 = xmprintf("%s/sessions/%s.lua", scCache, leaf);
3186 3176
3187 qhashtbl_t *tnm = qhashtbl(0, 0); 3177 qhashtbl_t *tnm = qhashtbl(0, 0);
3188 ret = LuaToHash(Rd, t0, "toke_n_munchie", tnm, ret, &st, &now, "session"); 3178 ret = LuaToHash(Rd, t0, "toke_n_munchie", tnm, ret, &st, &now, "session");
@@ -3516,7 +3506,7 @@ static int validateName(reqData *Rd, qhashtbl_t *data)
3516 int rt = 0; 3506 int rt = 0;
3517 3507
3518 if (s) {s--; *s = '_'; s++;} 3508 if (s) {s--; *s = '_'; s++;}
3519 where = xmprintf("%s/var/lib/users/%s.lua", getStrH(Rd->configs, "scRoot"), name); 3509 where = xmprintf("%s/users/%s.lua", scData, name);
3520 rt = LuaToHash(Rd, where, "user", tnm, ret, &st, &now, "user"); 3510 rt = LuaToHash(Rd, where, "user", tnm, ret, &st, &now, "user");
3521 if (s) {s--; *s = '\0'; s++;} 3511 if (s) {s--; *s = '\0'; s++;}
3522 free(where); 3512 free(where);
@@ -4489,10 +4479,71 @@ jit library is loaded or the JIT compiler will not be activated.
4489 if ((tmp = configs->getstr(configs, "ToS", false)) != NULL) {ToS = tmp; D("Setting ToS = %s", ToS);} 4479 if ((tmp = configs->getstr(configs, "ToS", false)) != NULL) {ToS = tmp; D("Setting ToS = %s", ToS);}
4490 4480
4491 4481
4482 // Use a FHS compatible setup -
4483 if (strcmp("/", scRoot) == 0)
4484 {
4485 scBin = "/bin";
4486 scEtc = "/etc/opensim_SC";
4487 scLib = "/usr/lib/opensim_SC";
4488 scRun = "/run/opensim_SC";
4489 scBackup = "/var/backups/opensim_SC";
4490 scCache = "/var/cache/opensim_SC";
4491 scData = "/var/lib/opensim_SC";
4492 scLog = "/var/log/opensim_SC";
4493 }
4494 else if (strcmp("/usr/local", scRoot) == 0)
4495 {
4496 scBin = "/usr/local/bin";
4497 scEtc = "/usr/local/etc/opensim_SC";
4498 scLib = "/usr/local/lib/opensim_SC";
4499 scRun = "/run/opensim_SC";
4500 scBackup = "/var/local/backups/opensim_SC";
4501 scCache = "/var/local/cache/opensim_SC";
4502 scData = "/var/local/lib/opensim_SC";
4503 scLog = "/var/local/log/opensim_SC";
4504 }
4505 else // A place for everything to live, like /opt/opensim_SC
4506 {
4507 char *slsh = "";
4508
4509 if ('/' != scRoot[0])
4510 {
4511 E("scRoot is not an absolute path - %s.", scRoot);
4512 slsh = "/";
4513 }
4514 // The problem here is that OpenSim already uses /opt/opensim_SC/current/bin for all of it's crap, where they mix everything together.
4515 // Don't want it in the path.
4516 // Could put the .dlls into lib. Most of the rest is config files or common assets.
4517 // Or just slowly migrate opensim stuff to FHS.
4518 scBin = xmprintf("%s%s/bin", slsh, scRoot);
4519 scEtc = xmprintf("%s%s/etc", slsh, scRoot);
4520 scLib = xmprintf("%s%s/lib", slsh, scRoot);
4521 scRun = xmprintf("%s%s/var/run", slsh, scRoot);
4522 scBackup = xmprintf("%s%s/var/backups", slsh, scRoot);
4523 scCache = xmprintf("%s%s/var/cache", slsh, scRoot);
4524 scData = xmprintf("%s%s/var/lib", slsh, scRoot);
4525 scLog = xmprintf("%s%s/var/log", slsh, scRoot);
4526 }
4527
4492 if (isTmux || isWeb) 4528 if (isTmux || isWeb)
4493 { 4529 {
4494 char *d; 4530 char *d;
4495 4531
4532 if ((! qfile_exist(scBin)) && (! qfile_mkdir(scBin, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scBin);
4533 if ((! qfile_exist(scEtc)) && (! qfile_mkdir(scEtc, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scEtc);
4534 if ((! qfile_exist(scLib)) && (! qfile_mkdir(scLib, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scLib);
4535 if ((! qfile_exist(scRun)) && (! qfile_mkdir(scRun, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP, true))) C("Unable to create path %s", scRun);
4536 if ((! qfile_exist(scBackup)) && (! qfile_mkdir(scBackup, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scBackup);
4537 if ((! qfile_exist(scCache)) && (! qfile_mkdir(scCache, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scCache);
4538 if ((! qfile_exist(scData)) && (! qfile_mkdir(scData, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scData);
4539 if ((! qfile_exist(scLog)) && (! qfile_mkdir(scLog, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", scLog);
4540 tmp = xmprintf("%s/sessions", scCache);
4541 if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp);
4542 tmp = xmprintf("%s/users", scData);
4543 if ((! qfile_exist(tmp)) && (! qfile_mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP, true))) C("Unable to create path %s", tmp);
4544 free(tmp);
4545
4546
4496 mimeTypes = qhashtbl(0, 0); 4547 mimeTypes = qhashtbl(0, 0);
4497 mimeTypes->putstr(mimeTypes, "gz", "application/gzip"); 4548 mimeTypes->putstr(mimeTypes, "gz", "application/gzip");
4498 mimeTypes->putstr(mimeTypes, "js", "application/javascript"); 4549 mimeTypes->putstr(mimeTypes, "js", "application/javascript");
@@ -4746,7 +4797,7 @@ T("BODY");
4746 4797
4747 4798
4748 I("Started SledjChisl FCGI web %s request ROLE = %s, body is %s bytes, pid %d.", Rd->Method, Role, Length, getpid()); 4799 I("Started SledjChisl FCGI web %s request ROLE = %s, body is %s bytes, pid %d.", Rd->Method, Role, Length, getpid());
4749 I(" %s://%s%s -> %s/html%s", Rd->Scheme, Rd->Host, Rd->RUri, webRoot, Path); 4800 I(" %s://%s%s -> %s%s", Rd->Scheme, Rd->Host, Rd->RUri, webRoot, Path);
4750 4801
4751 4802
4752/* TODO - other headers may include - 4803/* TODO - other headers may include -
@@ -4780,7 +4831,7 @@ T("BODY");
4780 } 4831 }
4781 4832
4782 memset(toybuf, 0, sizeof(toybuf)); 4833 memset(toybuf, 0, sizeof(toybuf));
4783 snprintf(toybuf, sizeof(toybuf), "%s/html%s", webRoot, Path); 4834 snprintf(toybuf, sizeof(toybuf), "%s%s", webRoot, Path);
4784 HTMLfile *thisFile = checkHTMLcache(toybuf); 4835 HTMLfile *thisFile = checkHTMLcache(toybuf);
4785 if (NULL == thisFile) 4836 if (NULL == thisFile)
4786 { 4837 {
@@ -4935,7 +4986,7 @@ fcgiDone:
4935 if (!isTmux) 4986 if (!isTmux)
4936 { // Let's see if the proper tmux server is even running. 4987 { // Let's see if the proper tmux server is even running.
4937 memset(toybuf, 0, sizeof(toybuf)); 4988 memset(toybuf, 0, sizeof(toybuf));
4938 snprintf(toybuf, sizeof(toybuf), "%s %s/%s -q list-sessions 2>/dev/null | grep -q %s:", Tcmd, scRoot, Tsocket, Tconsole); 4989 snprintf(toybuf, sizeof(toybuf), "%s %s/%s -q list-sessions 2>/dev/null | grep -q %s:", Tcmd, scRun, Tsocket, Tconsole);
4939 i = system(toybuf); 4990 i = system(toybuf);
4940 if (WIFEXITED(i)) 4991 if (WIFEXITED(i))
4941 { 4992 {
@@ -4946,14 +4997,14 @@ fcgiDone:
4946 // After the session is created, we rely on the caches directory to be group sticky, so that anyone in the opensim group can attach to the tmux socket. 4997 // After the session is created, we rely on the caches directory to be group sticky, so that anyone in the opensim group can attach to the tmux socket.
4947 snprintf(toybuf, sizeof(toybuf), 4998 snprintf(toybuf, sizeof(toybuf),
4948 "sudo -Hu %s %s %s/%s new-session -d -s %s -n '%s' \\; split-window -bhp 50 -t '%s:' bash -c './sledjchisl; cd %s; bash'", 4999 "sudo -Hu %s %s %s/%s new-session -d -s %s -n '%s' \\; split-window -bhp 50 -t '%s:' bash -c './sledjchisl; cd %s; bash'",
4949 scUser, Tcmd, scRoot, Tsocket, Tconsole, Ttab, Tconsole, scRoot); 5000 scUser, Tcmd, scRun, Tsocket, Tconsole, Ttab, Tconsole, scRoot);
4950 i = system(toybuf); 5001 i = system(toybuf);
4951 if (!WIFEXITED(i)) 5002 if (!WIFEXITED(i))
4952 E("tmux new-session command failed!"); 5003 E("tmux new-session command failed!");
4953 } 5004 }
4954 // Join the session. 5005 // Join the session.
4955 memset(toybuf, 0, sizeof(toybuf)); 5006 memset(toybuf, 0, sizeof(toybuf));
4956 snprintf(toybuf, sizeof(toybuf), "%s %s/%s select-window -t '%s' \\; attach-session -t '%s'", Tcmd, scRoot, Tsocket, Tconsole, Tconsole); 5007 snprintf(toybuf, sizeof(toybuf), "%s %s/%s select-window -t '%s' \\; attach-session -t '%s'", Tcmd, scRun, Tsocket, Tconsole, Tconsole);
4957 i = system(toybuf); 5008 i = system(toybuf);
4958 if (!WIFEXITED(i)) 5009 if (!WIFEXITED(i))
4959 E("tmux attach-session command failed!"); 5010 E("tmux attach-session command failed!");
@@ -5001,7 +5052,7 @@ fcgiDone:
5001 I("%s is starting up.", name); 5052 I("%s is starting up.", name);
5002 memset(toybuf, 0, sizeof(toybuf)); 5053 memset(toybuf, 0, sizeof(toybuf));
5003 snprintf(toybuf, sizeof(toybuf), "%s %s/%s new-window -dn '%s' -t '%s:%d' 'cd %s/current/bin; mono OpenSim.exe -inidirectory=%s/config/%s'", 5054 snprintf(toybuf, sizeof(toybuf), "%s %s/%s new-window -dn '%s' -t '%s:%d' 'cd %s/current/bin; mono OpenSim.exe -inidirectory=%s/config/%s'",
5004 Tcmd, scRoot, Tsocket, name, Tconsole, i + 1, scRoot, scRoot, sim); 5055 Tcmd, scRun, Tsocket, name, Tconsole, i + 1, scRoot, scRoot, sim);
5005 int r = system(toybuf); 5056 int r = system(toybuf);
5006 if (!WIFEXITED(r)) 5057 if (!WIFEXITED(r))
5007 E("tmux new-window command failed!"); 5058 E("tmux new-window command failed!");