diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sledjchisl/sledjchisl.c | 307 |
1 files changed, 286 insertions, 21 deletions
diff --git a/src/sledjchisl/sledjchisl.c b/src/sledjchisl/sledjchisl.c index 35f6202..1883ff3 100644 --- a/src/sledjchisl/sledjchisl.c +++ b/src/sledjchisl/sledjchisl.c | |||
@@ -393,6 +393,7 @@ struct _reqData | |||
393 | qgrow_t *reply; | 393 | qgrow_t *reply; |
394 | // pageBuildFunction func; | 394 | // pageBuildFunction func; |
395 | struct timespec then; | 395 | struct timespec then; |
396 | boolean fromDb; | ||
396 | // boolean chillOut, vegOut; | 397 | // boolean chillOut, vegOut; |
397 | }; | 398 | }; |
398 | 399 | ||
@@ -3555,6 +3556,41 @@ char *getLevel(short level) | |||
3555 | return ret; | 3556 | return ret; |
3556 | } | 3557 | } |
3557 | 3558 | ||
3559 | typedef struct _systemFolders systemFolders; | ||
3560 | struct _systemFolders | ||
3561 | { | ||
3562 | char *name; | ||
3563 | short type; | ||
3564 | }; | ||
3565 | |||
3566 | systemFolders sysFolders[] = | ||
3567 | { | ||
3568 | {"My Inventory", 8}, | ||
3569 | {"Animations", 20}, | ||
3570 | {"Body Parts", 13}, | ||
3571 | {"Calling Cards", 2}, | ||
3572 | // {"Friends", 2}, | ||
3573 | // {"All", 2}, | ||
3574 | {"Clothing", 5}, | ||
3575 | {"Current Outfit", 46}, | ||
3576 | {"Favorites", 23}, | ||
3577 | {"Gestures", 21}, | ||
3578 | {"Landmarks", 3}, | ||
3579 | {"Lost And Found", 16}, | ||
3580 | {"Mesh", 49}, | ||
3581 | {"My Outfits", 48}, | ||
3582 | {"My Suitcase", 100}, // All the others are replicated inside. | ||
3583 | {"Notecards", 7}, | ||
3584 | {"Objects", 6}, | ||
3585 | {"Outfit", 47}, | ||
3586 | {"Photo Album", 15}, | ||
3587 | {"Scripts", 10}, | ||
3588 | {"Sounds", 1}, | ||
3589 | {"Textures", 0}, | ||
3590 | {"Trash", 14}, | ||
3591 | {NULL, -1} | ||
3592 | }; | ||
3593 | |||
3558 | static void accountWrite(reqData *Rd) | 3594 | static void accountWrite(reqData *Rd) |
3559 | { | 3595 | { |
3560 | char *uuid = getStrH(Rd->database, "UserAccounts.PrincipalID"); | 3596 | char *uuid = getStrH(Rd->database, "UserAccounts.PrincipalID"); |
@@ -3590,8 +3626,8 @@ static void accountWrite(reqData *Rd) | |||
3590 | getStrH(Rd->stuff, "email"), | 3626 | getStrH(Rd->stuff, "email"), |
3591 | getLevel(atoi(level)), | 3627 | getLevel(atoi(level)), |
3592 | level, | 3628 | level, |
3593 | 64, | ||
3594 | 0, | 3629 | 0, |
3630 | 1, | ||
3595 | getStrH(Rd->stuff, "passwordHash"), | 3631 | getStrH(Rd->stuff, "passwordHash"), |
3596 | getStrH(Rd->stuff, "passwordSalt"), | 3632 | getStrH(Rd->stuff, "passwordSalt"), |
3597 | uuid, | 3633 | uuid, |
@@ -3610,25 +3646,253 @@ static void accountWrite(reqData *Rd) | |||
3610 | int fd = notstdio(xcreate_stdio(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)); | 3646 | int fd = notstdio(xcreate_stdio(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR)); |
3611 | size_t l = strlen(tnm); | 3647 | size_t l = strlen(tnm); |
3612 | 3648 | ||
3613 | if (s) | 3649 | uuid_t binuuid; |
3614 | I("Creating user %s.", file); | 3650 | |
3615 | else | 3651 | uuid_clear(binuuid); |
3616 | C("Updating user %s.", file); | 3652 | if ((NULL != uuid) && ('\0' != uuid[0])) |
3617 | if (l != writeall(fd, tnm, l)) | 3653 | uuid_parse(uuid, binuuid); |
3618 | perror_msg("Writing %s", file); | 3654 | if ((NULL != uuid) && ('\0' != uuid[0]) && (!uuid_is_null(binuuid))) |
3619 | else | ||
3620 | { | 3655 | { |
3621 | char *name = Rd->stuff->getstr(Rd->stuff, "name", true); | 3656 | if (s) |
3622 | char *nm = xmprintf("%s/users/%s.lua", scData, qstrreplace("tr", name, " ", "_")); | 3657 | I("Creating user %s.", file); |
3658 | else | ||
3659 | I("Updating user %s.", file); | ||
3660 | if (l != writeall(fd, tnm, l)) | ||
3661 | perror_msg("Writing %s", file); | ||
3662 | else | ||
3663 | { | ||
3664 | char *name = Rd->stuff->getstr(Rd->stuff, "name", true); | ||
3665 | char *nm = xmprintf("%s/users/%s.lua", scData, qstrreplace("tr", name, " ", "_")); | ||
3666 | |||
3667 | free(file); | ||
3668 | file = xmprintf("%s.lua", Rd->shs.UUID); | ||
3669 | I("Symlinking %s to %s", file, nm); | ||
3670 | if (0 != symlink(file, nm)) | ||
3671 | perror_msg("Symlinking %s to %s", file, nm); | ||
3672 | free(nm); free(name); | ||
3673 | } | ||
3674 | xclose(fd); | ||
3675 | |||
3676 | short lvl = atoi(level); | ||
3677 | |||
3678 | if (0 <= lvl) // Note that http://opensimulator.org/wiki/Userlevel claims that 1 and above are "GOD_LIKE". | ||
3679 | { | ||
3680 | if (Rd->fromDb) | ||
3681 | { | ||
3682 | I("Updating database user %s.", getStrH(Rd->stuff, "name")); | ||
3683 | } | ||
3684 | else | ||
3685 | { | ||
3686 | // Setup the database stuff. | ||
3687 | static dbRequest *acntsI = NULL; | ||
3688 | if (NULL == acntsI) | ||
3689 | { | ||
3690 | static char *szi[] = | ||
3691 | { | ||
3692 | "FirstName", | ||
3693 | "LastName", | ||
3694 | "Email", | ||
3695 | "Created", | ||
3696 | "PrincipalID", | ||
3697 | "ScopeID", | ||
3698 | "UserLevel", | ||
3699 | "UserFlags", | ||
3700 | "UserTitle", | ||
3701 | // "ServiceURLs", // No worky "text", filled with crap. | ||
3702 | "active", | ||
3703 | NULL | ||
3704 | }; | ||
3705 | static char *szo[] = {NULL}; | ||
3706 | acntsI = xzalloc(sizeof(dbRequest)); | ||
3707 | acntsI->db = Rd->db; | ||
3708 | acntsI->table = "UserAccounts"; | ||
3709 | acntsI->inParams = szi; | ||
3710 | acntsI->outParams = szo; | ||
3711 | acntsI->where = ""; | ||
3712 | acntsI->type = CT_CREATE; | ||
3713 | dbRequests->addfirst(dbRequests, acntsI, sizeof(*acntsI)); | ||
3714 | } | ||
3715 | static dbRequest *authI = NULL; | ||
3716 | if (NULL == authI) | ||
3717 | { | ||
3718 | static char *szi[] = {"UUID", "passwordSalt", "passwordHash", "accountType", "webLoginKey", NULL}; | ||
3719 | static char *szo[] = {NULL}; | ||
3720 | authI = xzalloc(sizeof(dbRequest)); | ||
3721 | authI->db = Rd->db; | ||
3722 | authI->table = "auth"; | ||
3723 | authI->inParams = szi; | ||
3724 | authI->outParams = szo; | ||
3725 | authI->where = ""; | ||
3726 | authI->type = CT_CREATE; | ||
3727 | dbRequests->addfirst(dbRequests, authI, sizeof(*authI)); | ||
3728 | } | ||
3729 | static dbRequest *invFolderI = NULL; | ||
3730 | if (NULL == invFolderI) | ||
3731 | { | ||
3732 | static char *szi[] = | ||
3733 | { | ||
3734 | "agentID", | ||
3735 | "folderName", | ||
3736 | "type", // smallint(6) | ||
3737 | "version", // int(11) | ||
3738 | "folderID", | ||
3739 | "parentFolderID", | ||
3740 | NULL | ||
3741 | }; | ||
3742 | static char *szo[] = {NULL}; | ||
3743 | invFolderI = xzalloc(sizeof(dbRequest)); | ||
3744 | invFolderI->db = Rd->db; | ||
3745 | invFolderI->table = "inventoryfolders"; | ||
3746 | invFolderI->inParams = szi; | ||
3747 | invFolderI->outParams = szo; | ||
3748 | invFolderI->where = ""; | ||
3749 | invFolderI->type = CT_CREATE; | ||
3750 | dbRequests->addfirst(dbRequests, invFolderI, sizeof(*invFolderI)); | ||
3751 | } | ||
3752 | static dbRequest *gUserI = NULL; | ||
3753 | if (NULL == gUserI) | ||
3754 | { | ||
3755 | // static char *szi[] = {"UserID", "HomeRegionID", "HomePosition", "HomeLookAt", "LastRegionID", "LastPosition", "LastLookAt", "Online", "Login", "Logout", NULL}; | ||
3756 | static char *szi[] = {"UserID", NULL}; // All the defaults are what we would set anyway. | ||
3757 | static char *szo[] = {NULL}; | ||
3758 | gUserI = xzalloc(sizeof(dbRequest)); | ||
3759 | gUserI->db = Rd->db; | ||
3760 | gUserI->table = "GridUser"; | ||
3761 | gUserI->inParams = szi; | ||
3762 | gUserI->outParams = szo; | ||
3763 | gUserI->where = ""; | ||
3764 | gUserI->type = CT_CREATE; | ||
3765 | dbRequests->addfirst(dbRequests, gUserI, sizeof(*gUserI)); | ||
3766 | } | ||
3767 | |||
3768 | I("Creating database user %s %s.", uuid, getStrH(Rd->stuff, "name")); | ||
3769 | char *first = Rd->stuff->getstr(Rd->stuff, "name", true), *last = strchr(first, ' '); | ||
3770 | |||
3771 | // create user record. | ||
3772 | *last++ = '\0'; | ||
3773 | if (0 != dbDoSomething(acntsI, FALSE, | ||
3774 | first, | ||
3775 | last, | ||
3776 | getStrH(Rd->stuff, "email"), | ||
3777 | (strcmp("", getStrH(Rd->stuff, "created")) != 0) ? atoi(getStrH(Rd->stuff, "created")) : (int) Rd->shs.timeStamp[1].tv_sec, | ||
3778 | uuid, | ||
3779 | "00000000-0000-0000-0000-000000000000", | ||
3780 | atoi(level), | ||
3781 | 0, | ||
3782 | getLevel(atoi(level)), | ||
3783 | // "", // Defaults to NULL, empty string seems OK to. Then gets filled in later. | ||
3784 | 1 | ||
3785 | )) | ||
3786 | bitch(Rd, "Internal error.", "Failed to create UserAccounts record."); | ||
3787 | else | ||
3788 | { | ||
3789 | char uuidI[37], uuidR[37], uuidC[37], uuidS[37]; | ||
3790 | uuid_t binuuidI; | ||
3791 | int r = 0, i; | ||
3792 | |||
3793 | // Create inventory records. | ||
3794 | strcpy(uuidR, "00000000-0000-0000-0000-000000000000"); | ||
3795 | for (i = 0; (NULL != sysFolders[i].name) && (0 == r); i++) | ||
3796 | { | ||
3797 | uuid_generate_random(binuuidI); | ||
3798 | uuid_unparse_lower(binuuidI, uuidI); | ||
3799 | // TODO - should check there isn't a folder with this UUID already. | ||
3800 | D("Creating %s inventory folder for user %s.", sysFolders[i].name, getStrH(Rd->stuff, "name")); | ||
3801 | r += dbDoSomething(invFolderI, FALSE, uuid, sysFolders[i].name, sysFolders[i].type, 1, uuidI, uuidR); | ||
3802 | if (0 != r) | ||
3803 | bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); | ||
3804 | if (strcmp("My Inventory", sysFolders[i].name) == 0) | ||
3805 | strcpy(uuidR, uuidI); | ||
3806 | if (strcmp("Calling Cards", sysFolders[i].name) == 0) | ||
3807 | strcpy(uuidC, uuidI); | ||
3808 | if (strcmp("My Suitcase", sysFolders[i].name) == 0) | ||
3809 | strcpy(uuidS, uuidI); | ||
3810 | } | ||
3811 | |||
3812 | uuid_generate_random(binuuidI); | ||
3813 | uuid_unparse_lower(binuuidI, uuidI); | ||
3814 | // TODO - should check there isn't a folder with this UUID already. | ||
3815 | D("Creating %s inventory folder for user %s.", "Friends", getStrH(Rd->stuff, "name")); | ||
3816 | r += dbDoSomething(invFolderI, FALSE, uuid, "Friends", 2, 1, uuidI, uuidC); | ||
3817 | if (0 != r) | ||
3818 | bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); | ||
3819 | strcpy(uuidC, uuidI); | ||
3820 | |||
3821 | uuid_generate_random(binuuidI); | ||
3822 | uuid_unparse_lower(binuuidI, uuidI); | ||
3823 | // TODO - should check there isn't a folder with this UUID already. | ||
3824 | D("Creating %s inventory folder for user %s.", "All", getStrH(Rd->stuff, "name")); | ||
3825 | r += dbDoSomething(invFolderI, FALSE, uuid, "All", 2, 1, uuidI, uuidC); | ||
3826 | if (0 != r) | ||
3827 | bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); | ||
3828 | |||
3829 | for (i = 1; (NULL != sysFolders[i].name) && (0 == r); i++) | ||
3830 | { | ||
3831 | uuid_generate_random(binuuidI); | ||
3832 | uuid_unparse_lower(binuuidI, uuidI); | ||
3833 | // TODO - should check there isn't a folder with this UUID already. | ||
3834 | D("Creating %s inventory folder for user %s.", sysFolders[i].name, getStrH(Rd->stuff, "name")); | ||
3835 | r += dbDoSomething(invFolderI, FALSE, uuid, sysFolders[i].name, sysFolders[i].type, 1, uuidI, uuidS); | ||
3836 | if (0 != r) | ||
3837 | bitch(Rd, "Internal error.", "Failed to create invenoryFolder record."); | ||
3838 | } | ||
3839 | |||
3840 | if (0 == r) | ||
3841 | { | ||
3842 | // Create location record. | ||
3843 | D("Creating home and last positions for user %s.", getStrH(Rd->stuff, "name")); | ||
3844 | if (0 != dbDoSomething(gUserI, FALSE, uuid)) | ||
3845 | bitch(Rd, "Internal error.", "Failed to create GridUser record."); | ||
3846 | else | ||
3847 | { | ||
3848 | // Finally create auth record, so they can log in. | ||
3849 | D("Creating auth record for user %s %s.", uuid, getStrH(Rd->stuff, "name")); | ||
3850 | if (0 != dbDoSomething(authI, FALSE, uuid, getStrH(Rd->stuff, "passwordSalt"), getStrH(Rd->stuff, "passwordHash"), "UserAccount", "00000000-0000-0000-0000-000000000000")) | ||
3851 | bitch(Rd, "Internal error.", "Failed to create auth record."); | ||
3852 | } | ||
3853 | } | ||
3854 | |||
3855 | // load iar -m first last / password /opt/opensim_SC/backups/DefaultMember.IAR | ||
3856 | simList *sims = getSims(); | ||
3857 | struct sysinfo info; | ||
3858 | float la; | ||
3623 | 3859 | ||
3624 | free(file); | 3860 | sysinfo(&info); |
3625 | file = xmprintf("%s.lua", Rd->shs.UUID); | 3861 | la = info.loads[0]/65536.0; |
3626 | I("Symlinking %s to %s", file, nm); | 3862 | |
3627 | if (0 != symlink(file, nm)) | 3863 | for (i = 0; i < sims->num; i++) |
3628 | perror_msg("Symlinking %s to %s", file, nm); | 3864 | { |
3629 | free(nm); free(name); | 3865 | char *sim = sims->sims[i], *name = getSimName(sims->sims[i]); |
3866 | |||
3867 | if (checkSimIsRunning(sim)) | ||
3868 | { | ||
3869 | I("Loading default member IAR for %s %s in sim %s, this might take a couple of minutes.", first, last, name); | ||
3870 | char *c = xmprintf("%s %s/%s send-keys -t '%s:%d' 'load iar -m %s %s / password /opt/opensim_SC/backups/DefaultMember.IAR' Enter", | ||
3871 | Tcmd, scRun, Tsocket, Tconsole, i + 1, first, last); | ||
3872 | T(c); | ||
3873 | int r = system(c); | ||
3874 | if (!WIFEXITED(r)) | ||
3875 | E("tmux load iar command failed!"); | ||
3876 | else | ||
3877 | { | ||
3878 | // memset(toybuf, 0, sizeof(toybuf)); | ||
3879 | // snprintf(toybuf, sizeof(toybuf), "INITIALIZATION COMPLETE FOR %s", name); | ||
3880 | // waitTmuxText(name, toybuf); | ||
3881 | // I("%s is done starting up.", name); | ||
3882 | // la = waitLoadAverage(la, loadAverageInc, simTimeOut); | ||
3883 | } | ||
3884 | free(c); | ||
3885 | break; | ||
3886 | } | ||
3887 | } | ||
3888 | |||
3889 | } | ||
3890 | free(first); | ||
3891 | } | ||
3892 | } | ||
3630 | } | 3893 | } |
3631 | xclose(fd); | 3894 | else |
3895 | W("Not writing NULL UUID user!"); | ||
3632 | free(tnm); | 3896 | free(tnm); |
3633 | free(voucher); | 3897 | free(voucher); |
3634 | free(about); | 3898 | free(about); |
@@ -4694,6 +4958,8 @@ static int accountRead(reqData *Rd, char *uuid, char *firstName, char *lastName) | |||
4694 | dbRequests->addfirst(dbRequests, auth, sizeof(*auth)); | 4958 | dbRequests->addfirst(dbRequests, auth, sizeof(*auth)); |
4695 | } | 4959 | } |
4696 | 4960 | ||
4961 | Rd->fromDb = FALSE; | ||
4962 | |||
4697 | // uuid = Rd->shs.UUID; first = getStrH(Rd->stuff, "firstName"); last = getStrH(Rd->stuff, "lastName"); | 4963 | // uuid = Rd->shs.UUID; first = getStrH(Rd->stuff, "firstName"); last = getStrH(Rd->stuff, "lastName"); |
4698 | 4964 | ||
4699 | // Special for showing another users details. | 4965 | // Special for showing another users details. |
@@ -4783,7 +5049,6 @@ d("accountRead() UUID %s, name %s %s", uuid, first, last); | |||
4783 | } | 5049 | } |
4784 | else if (rows) | 5050 | else if (rows) |
4785 | { | 5051 | { |
4786 | |||
4787 | ret += rows->rows->size(rows->rows); | 5052 | ret += rows->rows->size(rows->rows); |
4788 | if (1 == ret) | 5053 | if (1 == ret) |
4789 | { | 5054 | { |
@@ -4791,6 +5056,7 @@ d("accountRead() UUID %s, name %s %s", uuid, first, last); | |||
4791 | 5056 | ||
4792 | char *name = xmprintf("%s %s", getStrH(Rd->database, "UserAccounts.FirstName"), getStrH(Rd->database, "UserAccounts.LastName")); | 5057 | char *name = xmprintf("%s %s", getStrH(Rd->database, "UserAccounts.FirstName"), getStrH(Rd->database, "UserAccounts.LastName")); |
4793 | 5058 | ||
5059 | Rd->fromDb = TRUE; | ||
4794 | Rd->database->putstr(Rd->database, "Lua.name", name); | 5060 | Rd->database->putstr(Rd->database, "Lua.name", name); |
4795 | free(name); | 5061 | free(name); |
4796 | dbDoSomething(auth, FALSE, getStrH(Rd->database, "UserAccounts.PrincipalID")); | 5062 | dbDoSomething(auth, FALSE, getStrH(Rd->database, "UserAccounts.PrincipalID")); |
@@ -5154,7 +5420,7 @@ static int accountFilterValidated(struct dirtree *node) | |||
5154 | struct stat st; | 5420 | struct stat st; |
5155 | struct timespec now; | 5421 | struct timespec now; |
5156 | RdAndListTbl *rdl = (RdAndListTbl *) node->parent->extra; | 5422 | RdAndListTbl *rdl = (RdAndListTbl *) node->parent->extra; |
5157 | qhashtbl_t *tnm = qhashtbl(0, 0); | 5423 | qhashtbl_t *tnm = qhashtbl(0, 0); // LEAKY! |
5158 | char *name = node->name; | 5424 | char *name = node->name; |
5159 | char *where = xmprintf("%s/users/%s", scData, node->name); | 5425 | char *where = xmprintf("%s/users/%s", scData, node->name); |
5160 | int rt = LuaToHash(rdl->Rd, where, "user", tnm, 0, &st, &now, "user"); | 5426 | int rt = LuaToHash(rdl->Rd, where, "user", tnm, 0, &st, &now, "user"); |
@@ -5488,7 +5754,7 @@ void account_html(char *file, reqData *Rd, HTMLfile *thisFile) | |||
5488 | accountLevels->putstr(accountLevels, "-200", "newbie"); | 5754 | accountLevels->putstr(accountLevels, "-200", "newbie"); |
5489 | accountLevels->putstr(accountLevels, "-100", "validated"); | 5755 | accountLevels->putstr(accountLevels, "-100", "validated"); |
5490 | accountLevels->putstr(accountLevels, "-50", "vouched for"); | 5756 | accountLevels->putstr(accountLevels, "-50", "vouched for"); |
5491 | accountLevels->putstr(accountLevels, "1", "approved"); | 5757 | accountLevels->putstr(accountLevels, "0", "approved"); // Note that http://opensimulator.org/wiki/Userlevel claims that 1 and above are "GOD_LIKE". |
5492 | accountLevels->putstr(accountLevels, "200", "god"); | 5758 | accountLevels->putstr(accountLevels, "200", "god"); |
5493 | } | 5759 | } |
5494 | 5760 | ||
@@ -6613,7 +6879,6 @@ fcgiDone: | |||
6613 | } | 6879 | } |
6614 | 6880 | ||
6615 | 6881 | ||
6616 | |||
6617 | simList *sims = getSims(); | 6882 | simList *sims = getSims(); |
6618 | if (1) | 6883 | if (1) |
6619 | { | 6884 | { |