Ejemplo n.º 1
0
void ticksize_command(const char *arg, struct session *ses)
{
    int x;
    char left[BUFFER_SIZE], *err;

    get_arg(arg, left, 1, ses);
    if (!ses)
    {
        tintin_printf(ses, "#NO SESSION ACTIVE => NO TICKER!");
        return;
    }
    if (!*left || !isadigit(*left))
    {
        tintin_eprintf(ses, "#SYNTAX: #ticksize <number>");
        return;
    }
    x=strtol(left, &err, 10);
    if (*err || x<1 || x>=0x7fffffff)
    {
        tintin_eprintf(ses, "#TICKSIZE OUT OF RANGE (1..%d)", 0x7fffffff);
        return;
    }
    ses->tick_size = x;
    ses->time0 = time(NULL);
    tintin_printf(ses, "#OK. NEW TICKSIZE SET");
}
Ejemplo n.º 2
0
void pretick_command(const char *arg, struct session *ses)
{
    int x;
    char left[BUFFER_SIZE], *err;

    get_arg(arg, left, 1, ses);
    if (!ses)
    {
        tintin_printf(ses, "#NO SESSION ACTIVE => NO TICKER!");
        return;
    }
    if (!*left)
        x=ses->pretick? 0 : 10;
    else
    {
        x=strtol(left, &err, 10);
        if (*err || x<0 || x>=0x7fffffff)
        {
            tintin_eprintf(ses, "#PRETICK VALUE OUT OF RANGE (0..%d)", 0x7fffffff);
            return;
        }
    }
    if (x>=ses->tick_size)
    {
        tintin_eprintf(ses, "#PRETICK (%d) has to be smaller than #TICKSIZE (%d)",
            x, ses->tick_size);
        return;
    }
    ses->pretick = x;
    ses->time10 = time(NULL);
    if (x)
        tintin_printf(ses, "#OK. PRETICK SET TO %d", x);
    else
        tintin_printf(ses, "#OK. PRETICK TURNED OFF");
}
Ejemplo n.º 3
0
void deathlog_command(const char *arg, struct session *ses)
{
    FILE *fh;
    char fname[BUFFER_SIZE], text[BUFFER_SIZE], temp[BUFFER_SIZE], lfname[BUFFER_SIZE];

    if (*arg)
    {
        arg = get_arg_in_braces(arg, temp, 0);
        arg = get_arg_in_braces(arg, text, 1);
        substitute_vars(temp, fname);
        substitute_myvars(fname, temp, ses);
        expand_filename(temp, fname, lfname);
        substitute_vars(text, temp);
        substitute_myvars(temp, text, ses);
        if ((fh = fopen(lfname, "a")))
        {
            cfprintf(fh, "%s\n", text);
            fclose(fh);
        }
        else
            tintin_eprintf(ses, "#ERROR: COULDN'T OPEN FILE {%s}.", fname);
    }
    else
        tintin_eprintf(ses, "#ERROR: valid syntax is: #deathlog <file> <text>");
}
Ejemplo n.º 4
0
void alias_command(const char *arg, struct session *ses)
{
    char left[BUFFER_SIZE], right[BUFFER_SIZE], *ch;

    arg = get_arg_in_braces(arg, left, 0);
    arg = get_arg_in_braces(arg, right, 1);

    if (*left && *right)
    {
        if ((ch=strchr(left, ' ')))
        {
            tintin_eprintf(ses, "#ERROR: aliases cannot contain spaces! Bad alias: {%s}", left);
            if (ch==left)
                return;
            *ch=0;
            tintin_printf(ses, "#Converted offending alias to {%s}.", left);
        }
        set_hash(ses->aliases, left, right);
        if (ses->mesvar[MSG_ALIAS])
            tintin_printf(ses, "#Ok. {%s} aliases {%s}.", left, right);
        alnum++;
        return;
    }
    show_hashlist(ses, ses->aliases, left,
        "#Defined aliases:",
        "#No match(es) found for {%s}.");
}
Ejemplo n.º 5
0
void read_complete(const char *arg, struct session *ses)
{
    FILE *myfile;
    char buffer[BUFFER_SIZE];
    bool flag = true;
    struct completenode *tcomplete, *tcomp2;

    if (!(complete_head = (struct completenode *)(malloc(sizeof(struct completenode)))))
    {
        fprintf(stderr, "couldn't alloc completehead\n");
        user_done();
        exit(1);
    }
    tcomplete = complete_head;

    if (!(myfile = fopen("tab.txt", "r")))
    {
        if (const char *cptr = getenv("HOME"))
        {
            snprintf(buffer, BUFFER_SIZE, "%s/.tab.txt", cptr);
            myfile = fopen(buffer, "r");
        }
    }
    if (!myfile)
    {
        tintin_eprintf(0, "no tab.txt file, no completion list");
        return;
    }
    while (fgets(buffer, sizeof(buffer), myfile))
    {
        char *cptr;
        for (cptr = buffer; *cptr && *cptr != '\n'; cptr++) ;
        *cptr = '\0';
        if (!(tcomp2 = (struct completenode *)(malloc(sizeof(struct completenode)))))
        {
            fprintf(stderr, "couldn't alloc completehead\n");
            user_done();
            exit(1);
        }
        if (!(cptr = (char *)(malloc(strlen(buffer) + 1))))
        {
            fprintf(stderr, "couldn't alloc memory for string in complete\n");
            user_done();
            exit(1);
        }
        strcpy(cptr, buffer);
        tcomp2->strng = cptr;
        tcomplete->next = tcomp2;
        tcomplete = tcomp2;
    }
    tcomplete->next = NULL;
    fclose(myfile);
    tintin_printf(0, "tab.txt file loaded.");
    tintin_printf(0, "");

}
Ejemplo n.º 6
0
void unlink_command(const char *arg, struct session *ses)
{
    char file[BUFFER_SIZE], temp[BUFFER_SIZE], lstr[BUFFER_SIZE];

    if (*arg)
    {
        arg = get_arg_in_braces(arg, temp, 1);
        substitute_vars(temp, file);
        substitute_myvars(file, temp, ses);
        expand_filename(temp, file, lstr);
        unlink(lstr);
    }
    else
        tintin_eprintf(ses, "#ERROR: valid syntax is: #unlink <filename>");

}
Ejemplo n.º 7
0
void unroute_command(const char *arg, struct session *ses)
{
    char a[BUFFER_SIZE], b[BUFFER_SIZE];
    bool found=false;

    arg=get_arg(arg, a, 0, ses);
    arg=get_arg(arg, b, 1, ses);

    if ((!*a)||(!*b))
    {
        tintin_eprintf(ses, "#SYNTAX: #unroute <from> <to>");
        return;
    }

    for (int i=0;i<MAX_LOCATIONS;i++)
        if (ses->locations[i]&&match(a, ses->locations[i]))
            for (struct routenode**r=&ses->routes[i];*r;)
            {
                if (match(b, ses->locations[(*r)->dest]))
                {
                    struct routenode *p=*r;
                    if (ses->mesvar[MSG_ROUTE])
                    {
                        tintin_printf(ses, "#Ok. There is no longer a route from {%s~-1~} to {%s~-1~}.",
                            ses->locations[i],
                            ses->locations[p->dest]);
                    }
                    found=true;
                    *r=(*r)->next;
                    SFREE(p->path);
                    SFREE(p->cond);
                    TFREE(p, struct routenode);
                }
                else
                    r=&((*r)->next);
            }
    if (found)
        kill_unused_locations(ses);
    else if (ses->mesvar[MSG_ROUTE])
        tintin_printf(ses, "#THAT ROUTE (%s) IS NOT DEFINED.", b);
}
Ejemplo n.º 8
0
int do_telnet_protocol(const char *data, int nb, struct session *ses)
{
    const unsigned char *cp = (const unsigned char*)data+1;
    unsigned char wt;
    unsigned char answer[3];
    unsigned char nego[128], *np;

#define NEXTCH  cp++;                               \
                if (cp-(unsigned char*)data>=nb)    \
                    return -1;

    if (nb<2)
        return -1;
    switch (*cp)
    {
    case WILL:
    case WONT:
    case DO:
    case DONT:
        if (nb<3)
            return -1;
        wt=*(cp++);
#ifdef TELNET_DEBUG
        tintin_printf(ses, "~8~[telnet] received: IAC %s <%u> (%s)~-1~",
                      will_names[wt-251], *cp,
                      (*cp<sizeof(option_names)/sizeof(char*))?
                          option_names[*cp]:"?");
#endif
        answer[0]=IAC;
        answer[2]=*cp;
        switch (*cp)
        {
        case ECHO:
            switch (wt)
            {
            case WILL:  answer[1]=DO;   ses->server_echo=1; break;
            case DO:    answer[1]=WONT; break;
            case WONT:  answer[1]=DONT; ses->server_echo=2; break;
            case DONT:  answer[1]=WONT; break;
            }
            break;
        case TERMINAL_TYPE:
            switch (wt)
            {
            case WILL:  answer[1]=DONT; break;
            case DO:    answer[1]=WILL; break;
            case WONT:  answer[1]=DONT; break;
            case DONT:  answer[1]=WONT; break;
            }
            break;
        case NAWS:
            switch (wt)
            {
            case WILL:  answer[1]=DO;   ses->naws=false; break;
            case DO:    answer[1]=WILL; ses->naws=(LINES>1 && COLS>0); break;
            case WONT:  answer[1]=DONT; ses->naws=false; break;
            case DONT:  answer[1]=WONT; ses->naws=false; break;
            }
            break;
        case END_OF_RECORD:
            switch (wt)
            {
            case WILL:  answer[1]=DO;   break;
            case DO:    answer[1]=WONT; break;
            case WONT:  answer[1]=DONT; break;
            case DONT:  answer[1]=WONT; break;
            }
            break;
#ifdef HAVE_ZLIB
        case COMPRESS2:
            switch (wt)
            {
            case WILL:  answer[1]=DO;   ses->can_mccp=time(0)-ses->sessionstart<60; break;
            case DO:    answer[1]=WONT; break;
            case WONT:  answer[1]=DONT; ses->can_mccp=false; break;
            case DONT:  answer[1]=WONT; break;
            }
            break;
#endif
        default:
            switch (wt)
            {
            case WILL:  answer[1]=DONT; break;
            case DO:    answer[1]=WONT; break;
            case WONT:  answer[1]=DONT; break;
            case DONT:  answer[1]=WONT; break;
            }
        }
        write_socket(ses, (char*)answer, 3);
#ifdef TELNET_DEBUG
        tintin_printf(ses, "~8~[telnet] sent: IAC %s <%u> (%s)~-1~",
                      will_names[answer[1]-251], *cp,
                      (*cp<sizeof(option_names)/sizeof(char*))?
                          option_names[*cp]:"?");
#endif
        if (*cp==NAWS)
            telnet_send_naws(ses);
        return 3;
    case SB:
        np=nego;
sbloop:
        NEXTCH;
        while (*cp!=IAC)
        {
            if (np-nego>MAX_SUBNEGO_LENGTH)
                goto nego_too_long;
            *np++=*cp;
            NEXTCH;
        }
        NEXTCH;
        if (*cp==IAC)
        {
            if (np-nego>MAX_SUBNEGO_LENGTH)
                goto nego_too_long;
            *np++=IAC;
            goto sbloop;
        }
        if (*cp!=SE)
        {
            if (np-nego>MAX_SUBNEGO_LENGTH)
                goto nego_too_long;
            *np++=*cp;
            goto sbloop;
        }
        nb=cp-(unsigned char*)data;
#ifdef TELNET_DEBUG
        {
            char buf[BUFFER_SIZE], *b=buf;
            unsigned int neb=np-nego;
            np=nego;
            b=buf+sprintf(buf, "IAC SB ");
            switch (*np)
            {
            case TERMINAL_TYPE:
                b+=sprintf(b, "TERMINAL-TYPE ");
                if (*++np==SEND)
                {
                    b+=sprintf(b, "SEND ");
                    ++np;
                }
                break;
            case COMPRESS2:
                b+=sprintf(b, "COMPRESS2 ");
                np++;
            }
            while (np-nego<neb)
                b+=sprintf(b, "<%u> ", *np++);
            b+=sprintf(b, "IAC SE");
            tintin_printf(ses, "~8~[telnet] received: %s~-1~", buf);
        }
#endif
        switch (*(np=nego))
        {
        case TERMINAL_TYPE:
            if (*(np+1)==SEND)
                telnet_send_ttype(ses);
            break;
#ifdef HAVE_ZLIB
        case COMPRESS2:
            if (ses->can_mccp)
                return -4; /* compressed data immediately follows, we need to return */
#endif
        }
        return nb+1;
    case GA:
    case EOR:
#ifdef TELNET_DEBUG
        tintin_printf(ses, "~8~[telnet] received: IAC %s~-1~",
            (*cp==GA)?"GA":"EOR");
#endif
        ses->gas=true;
        return -2;
    case IAC:       /* IAC IAC is the escape for literal 255 byte */
        return -3;
    default:
        /* other 2-byte command, ignore */
#ifdef TELNET_DEBUG
        tintin_printf(ses, "~8~[telnet] received: IAC <%u>~-1~", *cp&255);
#endif
        return 2;
    }
    /* not reached */
    return cp-(unsigned char*)data;
nego_too_long:
    tintin_eprintf(ses, "#error: unterminated TELNET subnegotiation received.");
    return 2; /* we leave everything but IAC SB */
}
Ejemplo n.º 9
0
void help_command(const char *arg, struct session *ses)
{
    FILE *myfile=NULL;
    char text[BUFFER_SIZE], line[BUFFER_SIZE], filestring[BUFFER_SIZE];

    if (strcmp(DEFAULT_FILE_DIR, "HOME"))
    {
        sprintf(filestring, "%s/KBtin_help", DEFAULT_FILE_DIR);
        myfile = check_file(filestring);
    }
#ifdef DATA_PATH
    if (!myfile)
    {
        sprintf(filestring, "%s/KBtin_help", DATA_PATH);
        myfile = check_file(filestring);
    }
#endif
    if (!myfile)
    {
        sprintf(filestring, "%s_help", tintin_exec);
        myfile = check_file(filestring);
    }
    if (!myfile)
    {
        sprintf(filestring, "%s/KBtin_help", getenv("HOME"));
        myfile = check_file(filestring);
    }
    if (!myfile)
    {
        tintin_eprintf(0, "#Help file not found - no help available.");
        tintin_eprintf(0, "#Locations checked:");
        if (strcmp(DEFAULT_FILE_DIR, "HOME"))
            tintin_eprintf(0, "#      %s/KBtin_help%s", DEFAULT_FILE_DIR,
                COMPRESSION_EXT);
#ifdef DATA_PATH
        tintin_eprintf(0, "#      %s/KBtin_help%s", DATA_PATH,
            COMPRESSION_EXT);
#endif
        tintin_eprintf(0, "#      %s_help%s", tintin_exec,
            COMPRESSION_EXT);
        tintin_eprintf(0, "#      %s/KBtin_help%s", getenv("HOME"),
            COMPRESSION_EXT);
        return;
    }
    if (*arg==tintin_char)
        arg++;
    if (*arg)
    {
        sprintf(text, "~%s", arg);
        while (fgets(line, sizeof(line), myfile))
        {
            if (*line == '~')
            {
                if (*(line + 1) == '*')
                    break;
                if (is_abrev(text, line))
                {
                    while (fgets(line, sizeof(line), myfile))
                    {
                        if ((*line == '~')&&(*(line+1)=='~'))
                            goto end;
                        else
                        {
                            *(line + strlen(line) - 1) = '\0';
                            if (*line!='~')
                                tintin_printf(0, "%s", line);
                        }
                    }
                }
            }
        }
    }
    else
    {
        while (fgets(line, sizeof(line), myfile))
        {
            if ((*line == '~')&&(*(line+1)=='~'))
                goto end;
            else
            {
                *(line + strlen(line) - 1) = '\0';
                if (*line!='~')
                    tintin_printf(0, "%s", line);
            }
        }
    }
    tintin_printf(0, "#Sorry, no help on that word.");
end:
    fclose(myfile);
}
Ejemplo n.º 10
0
static void apply_options(void)
{
    char temp[BUFFER_SIZE], sname[BUFFER_SIZE];
    char ustr[BUFFER_SIZE];
    const char *home;
    FILE *f;
# define DO_INPUT(str,iv) local_to_utf8(ustr, str, BUFFER_SIZE, 0);\
                          activesession=parse_input(str, iv, activesession);

    for (struct listnode *opt=options->next; opt; opt=opt->next)
    {
        switch (*opt->left)
        {
        case '#':
            *opt->left=tintin_char;
            activesession=parse_input(opt->left, true, activesession);
            break;
        case 'c':
            DO_INPUT(opt->right, false);
            break;
        case 'r':
            set_magic_hook(activesession);
            make_name(sname, opt->right);
            snprintf(temp, BUFFER_SIZE,
                "%crun %.*s {%s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right);
            DO_INPUT(temp, true);
            break;
        case 's':
            set_magic_hook(activesession);
            make_name(sname, opt->right);
            snprintf(temp, BUFFER_SIZE,
                "%cses %.*s {%s %s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right, opt->pr);
            DO_INPUT(temp, true);
            break;
        case 'S':
            set_magic_hook(activesession);
            make_name(sname, opt->right);
            snprintf(temp, BUFFER_SIZE,
                "%csslses %.*s {%s %s}", tintin_char, MAX_SESNAME_LENGTH, sname, opt->right, opt->pr);
            DO_INPUT(temp, true);
            break;
        case ' ':
            local_to_utf8(ustr, opt->right, BUFFER_SIZE, 0);
            if ((f=fopen(opt->right, "r")))
            {
                if (activesession->verbose || !real_quiet)
                    tintin_printf(0, "#READING {%s}", ustr);
                activesession = do_read(f, ustr, activesession);
            }
            else
                tintin_eprintf(0, "#FILE NOT FOUND: {%s}", ustr);
            break;
        case '-':
            if (!strcmp(DEFAULT_FILE_DIR, "HOME"))
                if ((home = getenv("HOME")))
                    strcpy(temp, home);
                else
                    *temp = '\0';
            else
                strcpy(temp, DEFAULT_FILE_DIR);

            strcat(temp, "/.tintinrc");
            local_to_utf8(ustr, temp, BUFFER_SIZE, 0);
            if ((f=fopen(temp, "r")))
                activesession = do_read(f, ustr, activesession);
            else if ((home = getenv("HOME")))
            {
                strcpy(temp, home);
                strcat(temp, "/.tintinrc");
                local_to_utf8(ustr, temp, BUFFER_SIZE, 0);
                if ((f=fopen(temp, "r")))
                    activesession = do_read(f, ustr, activesession);
            }
        }
    }

    kill_list(options);
}
Ejemplo n.º 11
0
void dogoto_command(const char *arg, struct session *ses)
{
    char A[BUFFER_SIZE], B[BUFFER_SIZE],
        distvar[BUFFER_SIZE], locvar[BUFFER_SIZE], pathvar[BUFFER_SIZE];
    char left[BUFFER_SIZE], right[BUFFER_SIZE], tmp[BUFFER_SIZE], cond[BUFFER_SIZE];
    int a, b, i, j, s;
    int d[MAX_LOCATIONS], ok[MAX_LOCATIONS], way[MAX_LOCATIONS];
    char path[BUFFER_SIZE], *pptr;

    arg=get_arg(arg, A, 0, ses);
    arg=get_arg(arg, B, 0, ses);
    arg=get_arg(arg, distvar, 0, ses);
    arg=get_arg(arg, locvar, 0, ses);
    arg=get_arg(arg, pathvar, 0, ses);

    if ((!*A)||(!*B))
    {
        tintin_eprintf(ses, "#SYNTAX: #dogoto <from> <to> [<distvar> [<locvar> [<pathvar>]]] [#else ...]");
        return;
    }
    bool flag=*distvar||*locvar||*pathvar;

    for (a=0;a<MAX_LOCATIONS;a++)
        if (ses->locations[a]&&!strcmp(ses->locations[a], A))
            break;
    if (a==MAX_LOCATIONS)
        goto not_found;
    for (b=0;b<MAX_LOCATIONS;b++)
        if (ses->locations[b]&&!strcmp(ses->locations[b], B))
            break;
    if (b==MAX_LOCATIONS)
        goto not_found;
    for (i=0;i<MAX_LOCATIONS;i++)
    {
        d[i]=INF;
        ok[i]=0;
    }
    d[a]=0;
    do
    {
        s=INF;
        for (j=0;j<MAX_LOCATIONS;j++)
            if (!ok[j]&&(d[j]<s))
                s=d[i=j];
        if (s==INF)
            goto not_found;
        ok[i]=1;
        for (struct routenode *r=ses->routes[i];r;r=r->next)
            if (d[r->dest]>s+r->distance)
            {
                if (!*(r->cond))
                    goto good;
                substitute_vars(r->cond, tmp);
                substitute_myvars(tmp, cond, ses);
                if (eval_expression(cond, ses))
                {
                good:
                    d[r->dest]=s+r->distance;
                    way[r->dest]=i;
                }
            }
    } while (!ok[b]);
    sprintf(tmp, "%d", d[b]);
    if (*distvar)
        set_variable(distvar, tmp, ses);
    j=0;
    for (i=b;i!=a;i=way[i])
        d[j++]=i;
    d[j]=a;
    pptr=path;
    for (i=j;i>=0;i--)
        pptr+=snprintf(pptr, path-pptr+BUFFER_SIZE, " %s", ses->locations[d[i]]);
    pptr=path+(pptr!=path);
    if (*locvar)
        set_variable(locvar, pptr, ses);
    pptr=path;
    for (i=j;i>0;i--)
    {
        for (struct routenode *r=ses->routes[d[i]];r;r=r->next)
            if (r->dest==d[i-1])
            {
                if (flag)
                    pptr+=snprintf(pptr,
                        path-pptr+BUFFER_SIZE,
                        " {%s}",
                        r->path);
                else
                {
                    tintin_printf(ses, "%-10s>%-10s {%s}",
                        ses->locations[d[i]],
                        ses->locations[d[i-1]],
                        r->path);
                }
            }
    }
    pptr=path+(pptr!=path);
    if (*pathvar)
        set_variable(pathvar, pptr, ses);
    return;

not_found:
    arg=get_arg_in_braces(arg, left, 0);
    if (*left == tintin_char)
    {
        if (is_abrev(left + 1, "else"))
        {
            get_arg_in_braces(arg, right, 1);
            parse_input(right, true, ses);
            return;
        }
        if (is_abrev(left + 1, "elif"))
        {
            if_command(arg, ses);
            return;
        }
    }
    if (*left)
        tintin_eprintf(ses, "#ERROR: cruft after #dogoto: {%s}", left);
    if (!flag)
        tintin_printf(ses, "No paths from %s to %s found.", A, B);
}
Ejemplo n.º 12
0
void goto_command(const char *arg, struct session *ses)
{
    char A[BUFFER_SIZE], B[BUFFER_SIZE], tmp[BUFFER_SIZE], cond[BUFFER_SIZE];
    int a, b, i, j, s;
    int d[MAX_LOCATIONS], ok[MAX_LOCATIONS], way[MAX_LOCATIONS];
    char *path[MAX_LOCATIONS], *locs[MAX_LOCATIONS];

    arg=get_arg(arg, A, 0, ses);
    arg=get_arg(arg, B, 1, ses);

    if ((!*A)||(!*B))
    {
        tintin_eprintf(ses, "#SYNTAX: #goto <from> <to>");
        return;
    }

    for (a=0;a<MAX_LOCATIONS;a++)
        if (ses->locations[a]&&!strcmp(ses->locations[a], A))
            break;
    if (a==MAX_LOCATIONS)
    {
        tintin_eprintf(ses, "#Location not found: [%s]", A);
        return;
    }
    for (b=0;b<MAX_LOCATIONS;b++)
        if (ses->locations[b]&&!strcmp(ses->locations[b], B))
            break;
    if (b==MAX_LOCATIONS)
    {
        tintin_eprintf(ses, "#Location not found: [%s]", B);
        return;
    }
    for (i=0;i<MAX_LOCATIONS;i++)
    {
        d[i]=INF;
        ok[i]=0;
    }
    d[a]=0;
    do
    {
        s=INF;
        for (j=0;j<MAX_LOCATIONS;j++)
            if (!ok[j]&&(d[j]<s))
                s=d[i=j];
        if (s==INF)
        {
            tintin_eprintf(ses, "#No route from %s to %s!", A, B);
            return;
        }
        ok[i]=1;
        for (struct routenode *r=ses->routes[i];r;r=r->next)
            if (d[r->dest]>s+r->distance)
            {
                if (!*(r->cond))
                    goto good;
                substitute_vars(r->cond, tmp);
                substitute_myvars(tmp, cond, ses);
                if (eval_expression(cond, ses))
                {
                good:
                    d[r->dest]=s+r->distance;
                    way[r->dest]=i;
                }
            }
    } while (!ok[b]);
    j=0;
    for (i=b;i!=a;i=way[i])
        d[j++]=i;
    for (d[i=j]=a;i>0;i--)
    {
        locs[i]=mystrdup(ses->locations[d[i]]);
        for (struct routenode *r=ses->routes[d[i]];r;r=r->next)
            if (r->dest==d[i-1])
                path[i]=mystrdup(r->path);
    }

    /*
       we need to copy all used route data (paths and location names)
       because of ugly bad users who can use #unroute in the middle
       of a #go command
    */
    locs[0]=mystrdup(ses->locations[b]);
    for (i=j;i>0;i--)
    {
        if (ses->mesvar[MSG_GOTO])
        {
            tintin_printf(ses, "#going from %s to %s",
                locs[i],
                locs[i-1]);
        }
        parse_input(path[i], true, ses);
    }
    for (i=j;i>=0;i--)
        SFREE(locs[i]);
    for (i=j;i>0;i--)
        SFREE(path[i]);
    set_variable("loc", B, ses);
}
Ejemplo n.º 13
0
void route_command(const char *arg, struct session *ses)
{
    char a[BUFFER_SIZE], b[BUFFER_SIZE], way[BUFFER_SIZE], dist[BUFFER_SIZE], cond[BUFFER_SIZE];
    int j, d;

    arg=get_arg(arg, a, 0, ses);
    arg=get_arg(arg, b, 0, ses);
    arg=get_arg_in_braces(arg, way, 0);
    arg=get_arg(arg, dist, 0, ses);
    arg=get_arg_in_braces(arg, cond, 1);
    if (!*a)
    {
        tintin_printf(ses, "#THESE ROUTES HAVE BEEN DEFINED:");
        for (int i=0;i<MAX_LOCATIONS;i++)
            for (struct routenode *r=ses->routes[i];r;r=r->next)
                show_route(ses, i, r);
        return;
    }
    if (!*way)
    {
        bool first=true;
        if (!*b)
            strcpy(b, "*");
        for (int i=0;i<MAX_LOCATIONS;i++)
            if (ses->locations[i]&&match(a, ses->locations[i]))
                for (struct routenode *r=ses->routes[i];r;r=r->next)
                    if (ses->locations[i]&&
                          match(b, ses->locations[r->dest]))
                    {
                        if (first)
                        {
                            tintin_printf(ses, "#THESE ROUTES HAVE BEEN DEFINED:");
                            first=false;
                        }
                        show_route(ses, i, r);
                    }
        if (first)
            tintin_printf(ses, "#THAT ROUTE (%s) IS NOT DEFINED.", b);
        return;
    }
    int i;
    for (i=0;i<MAX_LOCATIONS;i++)
        if (ses->locations[i]&&!strcmp(ses->locations[i], a))
            goto found_i;
    if (i==MAX_LOCATIONS)
    {
        for (i=0;i<MAX_LOCATIONS;i++)
            if (!ses->locations[i])
            {
                ses->locations[i]=mystrdup(a);
                goto found_i;
            }
        tintin_eprintf(ses, "#TOO MANY LOCATIONS!");
        return;
    }
found_i:
    for (j=0;j<MAX_LOCATIONS;j++)
        if (ses->locations[j]&&!strcmp(ses->locations[j], b))
            goto found_j;
    if (j==MAX_LOCATIONS)
    {
        for (j=0;j<MAX_LOCATIONS;j++)
            if (!ses->locations[j])
            {
                ses->locations[j]=mystrdup(b);
                goto found_j;
            }
        tintin_eprintf(ses, "#TOO MANY LOCATIONS!");
        kill_unused_locations(ses);
        return;
    }
found_j:
    if (*dist)
    {
        char *err;
        d=strtol(dist, &err, 0);
        if (*err)
        {
            tintin_eprintf(ses, "#Hey! Route length has to be a number! Got {%s}.", arg);
            kill_unused_locations(ses);
            return;
        }
        if ((d<0)&&(ses->mesvar[MSG_ROUTE]||ses->mesvar[MSG_ERROR]))
            tintin_eprintf(ses, "#Error: distance cannot be negative!");
    }
    else
        d=DEFAULT_ROUTE_DISTANCE;
    addroute(ses, i, j, way, d, cond);
    if (ses->mesvar[MSG_ROUTE])
    {
        if (*cond)
            tintin_printf(ses, "#Ok. Way from {%s} to {%s} is now set to {%s} (distance=%i) condition:{%s}",
                ses->locations[i],
                ses->locations[j],
                way,
                d,
                cond);
        else
            tintin_printf(ses, "#Ok. Way from {%s} to {%s} is now set to {%s} (distance=%i)",
                ses->locations[i],
                ses->locations[j],
                way,
                d);
    }
    routnum++;
}