Esempio n. 1
0
/*
================
CL_LoadClientinfo

================
*/
void CL_LoadClientinfo (clientinfo_t *ci, char *s)
{
	int i;
	char		*t;
	//char		original_model_name[MAX_QPATH];
	//char		original_skin_name[MAX_QPATH];

	char		model_name[MAX_QPATH];
	char		skin_name[MAX_QPATH];
	char		model_filename[MAX_QPATH];
	char		skin_filename[MAX_QPATH];
	char		weapon_filename[MAX_QPATH];

	Q_strncpy(ci->cinfo, s, sizeof(ci->cinfo)-1);

	ci->deferred = false;

	// isolate the player's name
	Q_strncpy(ci->name, s, sizeof(ci->name)-1);

	i = 0;

	t = strchr (s, '\\');
	if (t)
	{
		if (t - s >= sizeof(ci->name)-1)
		{
			i = -1;
		}
		else
		{
			ci->name[t-s] = 0;
			s = t+1;
		}
	}

	//r1ch: check sanity of paths: only allow printable data
	t = s;
	while (*t)
	{
		//if (!isprint (*t))
		if (*t <= 32)
		{
			i = -1;
			break;
		}
		t++;
	}

	if (cl_noskins->intvalue || s[0] == 0 || i == -1)
	{
badskin:
		//strcpy (model_filename, "players/male/tris.md2");
		//strcpy (weapon_filename, "players/male/weapon.md2");
		//strcpy (skin_filename, "players/male/grunt.pcx");
		strcpy (ci->iconname, "/players/male/grunt_i.pcx");
		strcpy (model_name, "male");
		ci->model = re.RegisterModel ("players/male/tris.md2");
		//memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));
		//ci->weaponmodel[0] = re.RegisterModel (weapon_filename);
		ci->skin = re.RegisterSkin ("players/male/grunt.pcx");
		ci->icon = re.RegisterPic (ci->iconname);
	}
	else
	{
		int		length;
		int		j;

		Q_strncpy (model_name, s, sizeof(model_name)-1);

		t = strchr(model_name, '/');
		if (!t)
			t = strchr(model_name, '\\');

		if (!t)
		{
			memcpy (model_name, "male\0grunt\0\0\0\0\0\0", 16);
			s = "male\0grunt";
		}
		else
		{
			t[0] = 0;
		}

		//strcpy (original_model_name, model_name);

		// isolate the skin name
		Q_strncpy (skin_name, s + strlen(model_name) + 1, sizeof(skin_name)-1);
		//strcpy (original_skin_name, s + strlen(model_name) + 1);

		length = (int)strlen (model_name);
		for (j = 0; j < length; j++)
		{
			if (!isvalidchar(model_name[j]))
			{
				Com_DPrintf ("Bad character '%c' in playermodel '%s'\n", model_name[j], model_name);
				goto badskin;
			}
		}

		length = (int)strlen (skin_name);
		for (j = 0; j < length; j++)
		{
			if (!isvalidchar(skin_name[j]))
			{
				Com_DPrintf ("Bad character '%c' in playerskin '%s'\n", skin_name[j], skin_name);
				goto badskin;
			}
		}

		// model file
		Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name);
		ci->model = re.RegisterModel (model_filename);
		if (!ci->model)
		{
			ci->deferred = true;
			//if (!CL_CheckOrDownloadFile (model_filename))
			//	return;

			strcpy(model_name, "male");
			//Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");
			strcpy (model_filename, "players/male/tris.md2");
			ci->model = re.RegisterModel (model_filename);
		}

		// skin file
		Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
		ci->skin = re.RegisterSkin (skin_filename);

		if (!ci->skin)
		{
			//Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", original_model_name, original_skin_name);
			ci->deferred = true;
			//CL_CheckOrDownloadFile (skin_filename);
		}

		// if we don't have the skin and the model wasn't male,
		// see if the male has it (this is for CTF's skins)
 		if (!ci->skin && Q_stricmp(model_name, "male"))
		{
			// change model to male
			strcpy(model_name, "male");
			strcpy (model_filename, "players/male/tris.md2");
			ci->model = re.RegisterModel (model_filename);

			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);
			ci->skin = re.RegisterSkin (skin_filename);
		}

		// if we still don't have a skin, it means that the male model didn't have
		// it, so default to grunt
		if (!ci->skin) {
			// see if the skin exists for the male model
			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/grunt.pcx", model_name);
			ci->skin = re.RegisterSkin (skin_filename);
		}

		// icon file
		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name);
		ci->icon = re.RegisterPic (ci->iconname);

		if (!ci->icon) {
			//Com_sprintf (ci->iconname, sizeof(ci->iconname), "players/%s/%s_i.pcx", original_model_name, original_skin_name);
			ci->deferred = true;
			//ci->icon = re.RegisterPic ("/players/male/grunt_i.pcx");
		}
	}

	// weapon file
	for (i = 0; i < num_cl_weaponmodels; i++)
	{
		Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/%s", model_name, cl_weaponmodels[i]);
		ci->weaponmodel[i] = re.RegisterModel(weapon_filename);

		if (!ci->weaponmodel[i])
		{
			//Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", original_model_name, cl_weaponmodels[i]);
			ci->deferred = true;
		}

		if (!ci->weaponmodel[i] && strcmp(model_name, "cyborg") == 0)
		{
			// try male
			Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/%s", cl_weaponmodels[i]);
			ci->weaponmodel[i] = re.RegisterModel(weapon_filename);
		}

		if (!cl_vwep->intvalue)
			break; // only one when vwep is off
	}

	// must have loaded all data types to be valud
	if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0])
	{
		ci->skin = NULL;
		ci->icon = NULL;
		ci->model = NULL;
		ci->weaponmodel[0] = NULL;
		return;
	}
}
Esempio n. 2
0
static RNumCalcToken get_token(RNum *num, RNumCalc *nc) {
	char ch = 0, c = 0;

	do {
		if (!cin_get (num, nc, &ch)) {
			return nc->curr_tok = RNCEND;
		}
	} while (ch != '\n' && isspace ((ut8)ch));

	switch (ch) {
	case 0:
	case ';':
	case '\n':
		return nc->curr_tok = RNCEND;
	case '+':    // added for ++name and name++
		if (cin_get (num, nc, &c) && c == '+') {
			return nc->curr_tok = RNCINC;
		}
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	// negate hack
	case '~':
		if (cin_get (num, nc, &c) && c == '-') {
			return nc->curr_tok = RNCNEG;
		}
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	// negative number
	case '-':
		if (cin_get (num, nc, &c) && c == '-') {
			return nc->curr_tok = RNCDEC;
		}
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	case '^':
	case '&':
	case '|':
	case '*':
	case '%':
	case '/':
	case '(':
	case ')':
	case '<':
	case '>':
	case '=':
		return nc->curr_tok = (RNumCalcToken) ch;
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	case '.':
		cin_putback (num, nc, ch);
		if (!cin_get_num (num, nc, &nc->number_value)) {
			error (num, nc, "invalid number conversion");
			return 1;
		}
		return nc->curr_tok = RNCNUMBER;

#define isvalidchar(x) \
	(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
	|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || (x>='0'&&x<='9'))

	default:
		{
			int i = 0;
#define stringValueAppend(x) { \
	const size_t max = sizeof (nc->string_value) - 1; \
	if (i < max) nc->string_value[i++] = x; \
	else nc->string_value[max] = 0; \
}
			stringValueAppend(ch);
			if (ch == '[') {
				while (cin_get (num, nc, &ch) && ch!=']') {
					if (i > R_NUMCALC_STRSZ - 1) {
						error (num, nc, "string too long");
						return 0;
					}
					stringValueAppend(ch);
				}
				stringValueAppend(ch);
			} else {
				while (cin_get (num, nc, &ch) && isvalidchar ((unsigned char)ch)) {
					if (i >= R_NUMCALC_STRSZ) {
						error (num, nc, "string too long");
						return 0;
					}
					stringValueAppend(ch);
				}
			}
			stringValueAppend(0);
			if (ch!='\'') {
				cin_putback (num, nc, ch);
			}
			return nc->curr_tok = RNCNAME;
		}
	}
}
Esempio n. 3
0
/**
 * The /hs set command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
static int myDoSet(User * u)
{
    char *nick = strtok(NULL, " ");
    char *rawhostmask = strtok(NULL, " ");
    char *hostmask = smalloc(HOSTMAX);

    NickAlias *na;
    int32 tmp_time;
    char *s;

    char *vIdent = NULL;

    if (!nick || !rawhostmask) {
        syntax_error(s_HostServ, u, "SET", HOST_SET_SYNTAX);
        free(hostmask);
        return MOD_CONT;
    }

    vIdent = myStrGetOnlyToken(rawhostmask, '@', 0);    /* Get the first substring, @ as delimiter */
    if (vIdent) {
        rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1);      /* get the remaining string */
        if (!rawhostmask) {
            syntax_error(s_HostServ, u, "SET", HOST_SET_SYNTAX);
            free(vIdent);
            free(hostmask);
            return MOD_CONT;
        }
        if (strlen(vIdent) > USERMAX - 1) {
            notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX);
            free(vIdent);
            free(rawhostmask);
            free(hostmask);
            return MOD_CONT;
        } else {
            for (s = vIdent; *s; s++) {
                if (!isvalidchar(*s)) {
                    notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR);
                    free(vIdent);
                    free(rawhostmask);
                    free(hostmask);
                    return MOD_CONT;
                }
            }
        }
        if (!ircd->vident) {
            notice_lang(s_HostServ, u, HOST_NO_VIDENT);
            free(vIdent);
            free(rawhostmask);
            free(hostmask);
            return MOD_CONT;
        }
    }
    if (strlen(rawhostmask) < HOSTMAX)
        snprintf(hostmask, HOSTMAX, "%s", rawhostmask);
    else {
        notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX);
        if (vIdent) {
            free(vIdent);
            free(rawhostmask);
        }
        free(hostmask);
        return MOD_CONT;
    }

    if (!isValidHost(hostmask, 3)) {
        notice_lang(s_HostServ, u, HOST_SET_ERROR);
        if (vIdent) {
            free(vIdent);
            free(rawhostmask);
        }
        free(hostmask);
        return MOD_CONT;
    }


    tmp_time = time(NULL);

    if ((na = findnick(nick))) {
        if (na->status & NS_VERBOTEN) {
            notice_lang(s_HostServ, u, NICK_X_FORBIDDEN, nick);
            if (vIdent) {
                free(vIdent);
                free(rawhostmask);
            }
            free(hostmask);
            return MOD_CONT;
        }
        if (vIdent && ircd->vident) {
            alog("vHost for user \002%s\002 set to \002%s@%s\002 by oper \002%s\002", nick, vIdent, hostmask, u->nick);
        } else {
            alog("vHost for user \002%s\002 set to \002%s\002 by oper \002%s\002", nick, hostmask, u->nick);
        }
        addHostCore(nick, vIdent, hostmask, u->nick, tmp_time);
        if (vIdent) {
            notice_lang(s_HostServ, u, HOST_IDENT_SET, nick, vIdent,
                        hostmask);
        } else {
            notice_lang(s_HostServ, u, HOST_SET, nick, hostmask);
        }
    } else {
        notice_lang(s_HostServ, u, HOST_NOREG, nick);
    }
    free(hostmask);
    if (vIdent) {
        free(vIdent);
        free(rawhostmask);
    }
    return MOD_CONT;
}
Esempio n. 4
0
/**
 * @brief Validate a path supplied by a filelist.
 * @param[in,out] path Pointer to file (path) to download (high bits will be stripped).
 * @sa CL_QueueHTTPDownload
 * @sa CL_ParseFileList
 */
static void CL_CheckAndQueueDownload (char *path)
{
	size_t		length;
	const char	*ext;
	bool	pak;
	bool	gameLocal;

	StripHighBits(path);

	length = strlen(path);

	if (length >= MAX_QPATH)
		return;

	ext = Com_GetExtension(path);
	if (ext == NULL)
		return;

	if (Q_streq(ext, "pk3")) {
		Com_Printf("NOTICE: Filelist is requesting a .pk3 file (%s)\n", path);
		pak = true;
	} else
		pak = false;

	if (!pak &&
			!Q_streq(ext, "bsp") &&
			!Q_streq(ext, "wav") &&
			!Q_streq(ext, "md2") &&
			!Q_streq(ext, "ogg") &&
			!Q_streq(ext, "md3") &&
			!Q_streq(ext, "png") &&
			!Q_streq(ext, "jpg") &&
			!Q_streq(ext, "obj") &&
			!Q_streq(ext, "mat") &&
			!Q_streq(ext, "ump")) {
		Com_Printf("WARNING: Illegal file type '%s' in filelist.\n", path);
		return;
	}

	if (path[0] == '@') {
		if (pak) {
			Com_Printf("WARNING: @ prefix used on a pk3 file (%s) in filelist.\n", path);
			return;
		}
		gameLocal = true;
		path++;
		length--;
	} else
		gameLocal = false;

	if (strstr(path, "..") || !isvalidchar(path[0]) || !isvalidchar(path[length - 1]) || strstr(path, "//") ||
		strchr(path, '\\') || (!pak && !strchr(path, '/')) || (pak && strchr(path, '/'))) {
		Com_Printf("WARNING: Illegal path '%s' in filelist.\n", path);
		return;
	}

	/* by definition pk3s are game-local */
	if (gameLocal || pak) {
		bool exists;

		/* search the user homedir to find the pk3 file */
		if (pak) {
			char gamePath[MAX_OSPATH];
			FILE *f;
			Com_sprintf(gamePath, sizeof(gamePath), "%s/%s", FS_Gamedir(), path);
			f = fopen(gamePath, "rb");
			if (!f)
				exists = false;
			else {
				exists = true;
				fclose(f);
			}
		} else
			exists = FS_CheckFile("%s", path);

		if (!exists) {
			if (CL_QueueHTTPDownload(path)) {
				/* pk3s get bumped to the top and HTTP switches to single downloading.
				 * this prevents someone on 28k dialup trying to do both the main .pk3
				 * and referenced configstrings data at once. */
				if (pak) {
					dlqueue_t** anchor = &cls.downloadQueue;
					while ((*anchor)->next) anchor = &(*anchor)->next;
					/* Remove the last element from the end of the list ... */
					dlqueue_t* const d = *anchor;
					*anchor            = 0;
					/* ... and prepend it to the list. */
					d->next            = cls.downloadQueue;
					cls.downloadQueue  = d;
				}
			}
		}
	} else
		CL_CheckOrDownloadFile(path);
}
Esempio n. 5
0
int add_domain_to_acl(char *domain) {
        int state = 0;
        int len = strlen(domain);
        int i, c;

        struct dns_acl *dns_acl_curr;

        if (len > 63)
                return 0;

        for (i = 0; i < len; i++) {
                c = domain[i];
                switch (isvalidchar(c)) {
                case 1:
                        state = 1;
                        break;
                case 2:
                        switch (state) {
                        case 0: case 1: case 5: case 6:
                                state = 1;
                                break;
                        case 2: case 3: case 4:
                                state++;
                                break;
                        }
                        break;

                case 4:
                        switch (state) {
                        case 0: case 2:
                                state = -1;
                                break;
                        default:
                                state = 2;
                        }
                        break;
                case 6:
                        switch (state) {
                        case 0: case 2:
                                state = -1;
                                break;
                        default:
                                state = 6;
                        }
                        break;
                default:
                        /* Not valid chars */
                        return 0;
                }
        }

        /* Check exit code */
        switch (state) {
        case 1: case 4: case 5:
                /* Add name to domain ACL list */
                if ( (dns_acl_curr = malloc(sizeof(*dns_acl_curr))) == NULL) {
                        syslog(LOG_ERR,"Can't allocate memory for ACL, malloc error\n");
                        return 0;
                }
                strcpy(dns_acl_curr->domain, domain);
                dns_acl_curr->next = NULL;

                if (dns_acl_head == NULL)
                        dns_acl_head = dns_acl_curr;
                else
                        dns_acl_prev->next = dns_acl_curr;

                dns_acl_prev = dns_acl_curr;
                return 1;
        default:
                return 0;
        }
}
Esempio n. 6
0
static void CL_CheckAndQueueDownload (char *path)
{
    size_t		length;
    char		*ext;
    qboolean	pak;
    qboolean	gameLocal;

    StripHighBits (path, 1);

    length = strlen(path);

    if (length >= MAX_QPATH)
        return;

    ext = strrchr (path, '.');

    if (!ext)
        return;

    ext++;

    if (!ext[0])
        return;

    Q_strlwr (ext);

    if (!strcmp (ext, "pak"))
    {
        Com_Printf ("NOTICE: Filelist is requesting a .pak file (%s)\n", path);
        pak = true;
    }
    else
        pak = false;

    if (!pak && strcmp (ext, "pcx") && strcmp (ext, "wal") && strcmp (ext, "wav") && strcmp (ext, "md2") &&
            strcmp (ext, "sp2") && strcmp (ext, "tga") && strcmp (ext, "png") && strcmp (ext, "jpg") &&
            strcmp (ext, "bsp") && strcmp (ext, "ent") && strcmp (ext, "txt") && strcmp (ext, "dm2") &&
            strcmp (ext, "loc"))
    {
        Com_Printf ("WARNING: Illegal file type '%s' in filelist.\n", path);
        return;
    }

    if (path[0] == '@')
    {
        if (pak)
        {
            Com_Printf ("WARNING: @ prefix used on a pak file (%s) in filelist.\n", path);
            return;
        }
        gameLocal = true;
        path++;
        length--;
    }
    else
        gameLocal = false;

    if (strstr (path, "..") || !isvalidchar (path[0]) || !isvalidchar (path[length-1]) || strstr(path, "//") ||
            strchr (path, '\\') || (!pak && !strchr (path, '/')) || (pak && strchr(path, '/')))
    {
        Com_Printf ("WARNING: Illegal path '%s' in filelist.\n", path);
        return;
    }

    //by definition paks are game-local
    if (gameLocal || pak)
    {
        qboolean	exists;
        FILE		*f;
        char		gamePath[MAX_OSPATH];

        if (pak)
        {
            Com_sprintf (gamePath, sizeof(gamePath),"%s/%s",FS_Gamedir(), path);
            f = fopen (gamePath, "rb");
            if (!f)
            {
                exists = false;;
            }
            else
            {
                exists = true;
                fclose (f);
            }
        }
        else
        {
            exists = FS_ExistsInGameDir (path);
        }

        if (!exists)
        {
            if (CL_QueueHTTPDownload (path))
            {
                //paks get bumped to the top and HTTP switches to single downloading.
                //this prevents someone on 28k dialup trying to do both the main .pak
                //and referenced configstrings data at once.
                if (pak)
                {
                    dlqueue_t	*q, *last;

                    last = q = &cls.downloadQueue;

                    while (q->next)
                    {
                        last = q;
                        q = q->next;
                    }

                    last->next = NULL;
                    q->next = cls.downloadQueue.next;
                    cls.downloadQueue.next = q;
                }
            }
        }
    }
    else
    {
        CL_CheckOrDownloadFile (path);
    }
}
Esempio n. 7
0
static RNumCalcToken get_token(RNum *num, RNumCalc *nc) {
	char ch = 0, c = 0;

	do { if (!cin_get (num, nc, &ch)) return nc->curr_tok = RNCEND;
	} while (ch!='\n' && isspace ((unsigned char)ch));

	switch (ch) {
	case 0:
	case ';':
	case '\n':
		return nc->curr_tok = RNCEND;
	case '+':    // added for ++name and name++
		if (cin_get (num, nc, &c) && c == '+')
			return nc->curr_tok = RNCINC;
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	// negate hack
	case '~':
		if (cin_get (num, nc, &c) && c == '-')
			return nc->curr_tok = RNCNEG;
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	// negative number
	case '-':
		if (cin_get (num, nc, &c) && c == '-')
			return nc->curr_tok = RNCDEC;
		cin_putback (num, nc, c);
		return nc->curr_tok = (RNumCalcToken) ch;
	case '^':
	case '&':
	case '|':
	case '*':
	case '%':
	case '/':
	case '(':
	case ')':
	case '=':
		return nc->curr_tok = (RNumCalcToken) ch;
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	case '.':
		cin_putback (num, nc, ch);
		if (!cin_get_num (num, nc, &nc->number_value)) {
			error (num, nc, "invalid number conversion");
			return 1;
		}
		return nc->curr_tok = RNCNUMBER;

#define isvalidchar(x) \
	(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
	|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9'))

	default:
		{
			int i = 0;
			nc->string_value[i++] = ch;
			if (ch == '[') {
				while (cin_get (num, nc, &ch) && ch!=']') {
					if (i>=R_NUMCALC_STRSZ) {
						error (num, nc, "string too long");
						return 0;
					}
					nc->string_value[i++] = ch;
				}
				nc->string_value[i++] = ch;
			} else {
				while (cin_get (num, nc, &ch) && isvalidchar ((unsigned char)ch)) {
					if (i>=R_NUMCALC_STRSZ) {
						error (num, nc, "string too long");
						return 0;
					}
					nc->string_value[i++] = ch;
				}
			}
			nc->string_value[i] = 0;
			cin_putback (num, nc, ch);
			return nc->curr_tok = RNCNAME;
		}
/*
 * Unreacheable code:
		error (num, nc, "bad token");
		return nc->curr_tok = RNCPRINT;
*/
	}
}
Esempio n. 8
0
static RNumToken get_token() {
	char c, ch;

	do { if (!cin_get (&ch)) return curr_tok = END;
	} while (ch!='\n' && isspace (ch));

	switch (ch) {
	case 0:
	case ';':
	case '\n':
		return curr_tok = END;
	case '+':    // added for ++name and name++
		if (cin_get (&c) && c == '+')
			return curr_tok = INC;
		cin_putback (c);
		return curr_tok = (RNumToken) ch;
	case '-':
		if (cin_get (&c) && c == '-')
			return curr_tok = DEC;
		cin_putback (c);
		return curr_tok = (RNumToken) ch;
	case '*':
	case '/':
	case '(':
	case ')':
	case '=':
		return curr_tok = (RNumToken) ch;
	case '0':case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	case '.':
		cin_putback (ch);
		if (!cin_get_num (&number_value)) {
			error ("invalid number conversion");
			return 1;
		}
		return curr_tok = NUMBER;
	default:
#define isvalidchar(x) \
	(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
	|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9'))
{
			int i = 0;
			string_value[i++] = ch;
			if (ch == '[') {
				while (cin_get (&ch) && ch!=']') {
					if (i>=STRSZ) {
						error ("string too long");
						return 0;
					}
					string_value[i++] = ch;
				}
				string_value[i++] = ch;
			} else {
				while (cin_get (&ch) && isvalidchar (ch)) {
					if (i>=STRSZ) {
						error ("string too long");
						return 0;
					}
					string_value[i++] = ch;
				}
			}
			string_value[i] = 0;
			cin_putback (ch);

			return curr_tok = NAME;
}
		//}
		error ("bad token");
		return curr_tok = PRINT;
	}
}