Esempio n. 1
0
std::string Graph::nextName(std::string prefix) const
{
    unsigned i=0;
    while(1)
    {
        auto n = prefix + std::to_string(i++);
        if (isNameUnique(n))
            return n;
    }
}
Esempio n. 2
0
void Viewport::onPaste()
{
    auto data = QApplication::clipboard()->mimeData();
    if (data->hasFormat("sb::viewport"))
    {
        auto g = App::instance()->getGraph();
        const uint64_t new_uid = g->getUIDs(1).front();

        // Update this node's UID and store the change in uid_map
        auto n = QJsonDocument::fromJson(
                data->data("sb::viewport")).object();

        n["uid"] = int(new_uid);

        auto name = n["name"].toString();
        if (!g->isNameUnique(name.toStdString()))
        {
            // Trim trailing numbers from the node's name
            while (name.at(name.size() - 1).isNumber())
                name = name.left(name.size() - 1);
            if (name.isEmpty())
                name = "n";
            // Then use the remaining string as a prefix
            n["name"] = QString::fromStdString(g->nextName(name.toStdString()));
        }

        // Deserialize this node
        SceneDeserializer::Info ds;
        SceneDeserializer::deserializeNode(n, g, &ds);

        // Update the inspector positions by shifting a bit down and over
        for (auto& i : ds.inspectors)
            i += QPointF(10, 10);
        App::instance()->getGraphScene()->setInspectorPositions(ds.inspectors);

        App::instance()->pushStack(
                new UndoAddNodeCommand(g->childNodes().back(), "'paste'"));
    }
}
Esempio n. 3
0
// int cffsd_fsupdate_directory (u_int sn, int action, struct embdirent *dirent, u_int param2, u_int param3, u_int param4, u_int param5)
int serv_fsupdate_directory (u_int client_eid, int action, struct cffsd_fsupdate_directory_arg *arg)
{
    struct embdirent *dirent;
    u_int param2 = arg->param2;
    u_int param3 = arg->uint_param3;
    //  u_int param4 = arg->uint_param4;
    u_int param5 = arg->param5;

    u_int param1;
    /* XXX % */
    // char *dirBlock = (char *) translate_address ((param1 - (param1 % BLOCK_SIZE)), BLOCK_SIZE);
    char *dirBlock;

    debug_request = 3;

    dirent = translate_address (&arg->dirent);
    param1 = (u_int) dirent;
    dirBlock = (char *)((param1 - (param1 % BLOCK_SIZE)));

    if (dirBlock == NULL) {
        return (-E_INVAL);
    }

    /* XXX % */
    dirent = (embdirent_t *) (dirBlock + (param1 % BLOCK_SIZE));

    /* GROK -- need to check for write permission on directory.  The relevant  */
    /* inode should be provided automatically by base disk protection software */

    if (!isValidDirent(dirBlock, dirent)) {
        printf ("sys_fsupdate_directory (%d): invalid dirent specified (%x)\n", action, param1);
        return (-E_INVAL);
    }

    /************************** CFFS_DIRECTORY_INITDIRBLOCK ***********************/

    if (action == CFFS_DIRECTORY_INITDIRBLOCK) {
        int i;
        dinode_t *dinode;

        /* XXX */
        if ((u_int)dirent % BLOCK_SIZE) {
            printf ("sys_fsupdate_directory (%d): dirent not start of block (%p)\n", action, dirent);
            return (-E_INVAL);
        }

        bzero ((char *)dirent, BLOCK_SIZE);

        for (i=0; i<(BLOCK_SIZE/CFFS_EMBDIR_SECTOR_SIZE); i++) {
            dirent->type = (char) 0;
            dirent->entryLen = CFFS_EMBDIR_SECTOR_SPACEFORNAMES;
            dirent->preventryLen = 0;

            dinode = (dinode_t *) ((char *)dirent + CFFS_DINODE_SIZE);
            dinode->dinodeNum = 0;
            dinode = (dinode_t *) ((char *)dirent + (2*CFFS_DINODE_SIZE));
            dinode->dinodeNum = 0;
            dinode = (dinode_t *) ((char *)dirent + (3*CFFS_DINODE_SIZE));
            dinode->dinodeNum = 0;

            dirent = (embdirent_t *) ((char *) dirent + CFFS_EMBDIR_SECTOR_SIZE);
        }


        /*************************** CFFS_DIRECTORY_SPLITENTRY ************************/

    } else if (action == CFFS_DIRECTORY_SPLITENTRY) {
        embdirent_t *newDirent;
        int splitspace = param2;
        int extraspace;

        extraspace = (dirent->type == (char)0) ? dirent->entryLen : (dirent->entryLen - embdirentsize(dirent));
        if ((extraspace < SIZEOF_EMBDIRENT_T) || (extraspace < splitspace)) {
            printf ("sys_fsupdate_directory (%d): not enough extra space (%d) (wanted %d)\n", action, extraspace, splitspace);
            return (-E_INVAL);
        }

        if (splitspace == 0) {
            printf ("sys_fsupdate_directory (%d): bad splitspace (%d) (extraspace %d)\n", action, splitspace, extraspace);
            return (-E_INVAL);
        }

        dirent->entryLen -= splitspace;
        newDirent = (embdirent_t *) ((u_int)dirent + dirent->entryLen);
        if (newDirent != dirent) {
            newDirent->preventryLen = dirent->entryLen;
        }
        newDirent->entryLen = splitspace;
        newDirent->type = 0;
        newDirent->nameLen = 0;
        newDirent->name[0] = (char) 0;
        if (((u_int)newDirent + newDirent->entryLen) % CFFS_EMBDIR_SECTOR_SPACEFORNAMES) {
            dirent = (embdirent_t *) ((char *)newDirent + newDirent->entryLen);
            dirent->preventryLen = splitspace;
        }
        /* XXX % */
        //      ret = (param1 - (param1 % BLOCK_SIZE)) + ((u_int)newDirent - (u_int)dirBlock);
        return ((u_int )newDirent);

        /*************************** CFFS_DIRECTORY_SETNAME ************************/

    } else if (action == CFFS_DIRECTORY_SETNAME) {
        //     char *name = (char *) trup(param2); /* XXX */
        char name[256];

        u_int namelen = param3;
        dinode_t *dirDInode = translate_address (&arg->ref_param4);

        /* XXX -- I thought we only reserved < 128 bytes for names? */
        if (namelen > 256) {
            printf ("sys_fsupdate_directory (%d): name too long (%d)\n", action, namelen);
            return (-E_INVAL);
        }

        if (cffsd_copyin (client_eid, param2, (uint )name, namelen) == -1)
            return (-E_INVAL);

        if ((dirDInode == NULL) || (dirDInode->dinodeNum == 0)) {
            return (-E_INVAL);
        }

        /* Note: param5 is fsdev in this case, which should be discoverable */
        /* from the dinode's identity...                                    */
        if ((dirent->type != 0) && (!isNameUnique(param5, dirDInode, name, namelen))) {
            printf ("sys_fsupdate_directory (%d): non-unique name specified (%d)\n", action, namelen);
            return (-E_INVAL);
        }

        bcopy(name, dirent->name, namelen);
        //      dirent->name[namelen] = (char) 0;
        dirent->nameLen = namelen;

        /*************************** CFFS_DIRECTORY_MERGEENTRY ************************/

    } else if (action == CFFS_DIRECTORY_MERGEENTRY) {
        embdirent_t *next = NULL;
        int maxleft = CFFS_EMBDIR_SECTOR_SPACEFORNAMES - (param1 % CFFS_EMBDIR_SECTOR_SIZE);
        int extraspace = 0;

        while ((extraspace < param2) && (extraspace < maxleft)) {
            next = (embdirent_t *) ((char *)dirent + dirent->entryLen);
            if (next->type != 0) {
                break;
            }
            extraspace += next->entryLen;
        }

        if (extraspace != param2) {
            printf ("sys_fsupdate_directory (%d): mismatched extraspaces (%d != %d) (maxleft %d)\n", action, extraspace, param2, maxleft);
            printf ("next %p, next->entryLen %d\n", next, ((next) ? (next->entryLen) : -1));
            return (-E_INVAL);
        }

        dirent->entryLen += extraspace;
        next = (embdirent_t *) ((char *)dirent + dirent->entryLen);
        if ((u_int) next % CFFS_EMBDIR_SECTOR_SPACEFORNAMES) {
            next->preventryLen = dirent->entryLen;
        }

        /*************************** CFFS_DIRECTORY_SHIFTENTRY ************************/

    } else if (action == CFFS_DIRECTORY_SHIFTENTRY) {

        /********* Not currently supported! ************/
        assert (0);

#if 0
        embdirent_t *tmp;
        int extraspace;

        if ((-param2 > (param1 % CFFS_EMBDIR_SECTOR_SIZE)) || ((param2 + (param1 % CFFS_EMBDIR_SECTOR_SIZE)) >= (CFFS_EMBDIR_SECTOR_SPACEFORNAMES - SIZEOF_EMBDIRENT_T))) {
            printf ("sys_fsupdate_directory (%d): sizes don't work (currOff %d, move %d)\n", action, (param1 % BLOCK_SIZE), param2);
            return (-E_INVAL);
        }

        if (param2 <= 0) {
            tmp = (embdirent_t *) ((char *)dirent - dirent->preventryLen);
            extraspace = (tmp->type == (char)0) ? tmp->entryLen : tmp->entryLen - embdirentsize(tmp);
            if (extraspace < (-param2)) {
                printf ("sys_fsupdate_directory (%d): not enough extra space (%d < %d)\n", action, extraspace, param2);
                return (-E_INVAL);
            }
            tmp->entryLen -= (-param2);
            dirent->preventryLen = tmp->entryLen;
            dirent->entryLen += (-param2);
            bcopy ((char *) dirent, ((char *)dirent - (-param2)), embdirentsize(dirent));
            tmp = (embdirent_t *) ((char *)dirent + dirent->entryLen);
            if ((u_int) tmp % CFFS_EMBDIR_SECTOR_SPACEFORNAMES) {
                tmp->preventryLen = dirent->entryLen;
            }

        } else {
            tmp = (embdirent_t *) ((char *)dirent - dirent->preventryLen);
            extraspace = dirent->entryLen - embdirentsize(dirent);
            if (extraspace < param2) {
                printf ("sys_fsupdate_directory (%d): not enough extra space (%d < %d)\n", action, extraspace, param2);
                return (-E_INVAL);
            }
            tmp->entryLen += param2;
            dirent->preventryLen = tmp->entryLen;
            dirent->entryLen -= param2;
            bcopy ((char *)dirent, ((char *)dirent + param2), embdirentsize(dirent));
            dirent = (embdirent_t *) ((char *)dirent + tmp->entryLen);
            tmp = (embdirent_t *) ((char *)dirent + dirent->entryLen);
            if ((u_int) tmp % CFFS_EMBDIR_SECTOR_SPACEFORNAMES) {
                tmp->preventryLen = dirent->entryLen;
            }
        }
#endif

        /*************************** CFFS_DIRECTORY_SETINODENUM ***********************/

    } else if (action == CFFS_DIRECTORY_SETINODENUM) {
        u_int inodeNum = param2;

        /* no restrictions is directory entry is not currently live */
        if (dirent->type == 0) {
            dirent->inodeNum = inodeNum;

            /* this case causes a change in which inode a dirent points to.      */
            /* because the dirent is live, it must always point to a live inode. */
        } else {
            dinode_t *olddinode;
            dinode_t *newdinode;

            if (inodeNum == 0) {
                printf ("sys_fsupdate_directory (%d): can't set inodeNum to 0 is live dirent\n", action);
                return (-E_INVAL);
            }

            /*
                if ((param3 == 0) || (param4 == 0)) {
                   printf ("sys_fsupdate_directory (%d): passed NULL for a cheat variable (%d, %d)\n", action, param3, param4);
                   return (-E_INVAL);
                }
            */
            /* it is a bug in FS code to have valid dirent with 0 for an inodeNum */
            assert (dirent->inodeNum != 0);

            /* this should be retrievable from dirent->inodeNum, which identifies */
            /* the containing disk block -- which must be a directory block.      */
            olddinode = translate_address (&arg->ref_param3);
            if (olddinode->dinodeNum != dirent->inodeNum) {
                printf ("sys_fsupdate_directory (%d): mismatching old inodeNums (%d != %d)\n", action, olddinode->dinodeNum, dirent->inodeNum);
                return (-E_INVAL);
            }

            /* this should be retrievable from inodeNum, which identifies the */
            /* containing disk block -- which must be a directory block.     */
            newdinode = translate_address (&arg->ref_param4);
            if (newdinode->dinodeNum != inodeNum) {
                printf ("sys_fsupdate_directory (%d): mismatching old inodeNums (%d != %d)\n", action, newdinode->dinodeNum, inodeNum);
                return (-E_INVAL);
            }

            if ((olddinode->type != newdinode->type) && ((cffs_dinode_isDir(olddinode)) || (cffs_dinode_isDir(newdinode)))) {
                printf ("sys_fsupdate_directory (%d): can't interchange a directory and non-directory (%x != %x)\n", action, olddinode->type, newdinode->type);
                return (-E_INVAL);
            }

            /* this rule helps get us around an ordering requirement!! */
            /* (i.e., if we handle ordering in some other way, it can  */
            /* go away...                                              */
            if (newdinode->linkCount < (cffs_dinode_isDir(newdinode) ? 2 : 1)) {
                printf ("sys_fsupdate_directory (%d): can't link up to disowned inode\n", action);
                return (-E_INVAL);
            }

            /* the big stickler here is that we need to be able to check whether */
            /* the caller has the ability to look at newdinode.  In particular,  */
            /* this requires execute permission on a directory that already      */
            /* contains an existing link.                                        */

            if ((olddinode) && (cffs_dinode_isDir(olddinode))) {
                /* must check that directory is actually empty... */
            }

            /* GROK - I'm pretty sure I've designed away all need for ordering here */
            olddinode->linkCount--;
            newdinode->linkCount++;
            dirent->inodeNum = inodeNum;
            dirent->type = newdinode->type >> 8;
        }

        /**************************** CFFS_DIRECTORY_SETTYPE **************************/

    } else if (action == CFFS_DIRECTORY_SETTYPE) {