Beispiel #1
0
int
main(int argc, const char **argv)
{
	unsigned char proxy_header[MAX_HEADER_SIZE + 1];
	ssize_t n = 0;
	int address_len = 0;

	if (argc == 1)
		n = read(STDIN_FILENO, proxy_header, MAX_HEADER_SIZE);
	else if (argc == 2)
		n = read_from_socket(argv[1], proxy_header, MAX_HEADER_SIZE);
	else {
		fprintf(stderr, "Usage: parse_proxy_v2 [port]\n");
		return (1);
	}

	if (n < 16) {
		printf("ERROR:\tread too few bytes.\n");
		return (1);
	}
	proxy_header[n] = '\0';

	if (strncmp("PROXY TCP", (char *)proxy_header, 9) == 0) {
		/* PROXY version 1 over TCP */
		fprintf(stdout,
		    "ERROR:\tPROXY v1 parsing not supported in this tool.\n");
		return (1);
	} else if (memcmp(PROXY_V2_HEADER, proxy_header, 12) != 0) {
		printf("ERROR:\tNot a valid PROXY header\n");
		return (1);
	}
	printf("PROXY v2 detected.\n");
	switch (proxy_header[12]) {
	case 0x20:
		printf("ERROR:\tLOCAL connection\n");
		return (1);
	case 0x21:
		printf("Connection:\tPROXYed connection detected\n");
		break;
	default:
		printf("ERROR:\t13th byte has illegal value %d\n",
		    (int)proxy_header[12]);
		return (1);
	}
	switch (proxy_header[13]) {
	case 0x00:
		printf("ERROR:\tProtocol:\tUnspecified/unsupported\n");
		return (1);
	case 0x11:
		printf("Protocol:\tTCP over IPv4\n");
		address_len = 12;
		break;
	case 0x12:
		printf("Protocol:\tUDP over IPv4\n");
		printf("ERROR:\tProtocol unsupported in hitch seen\n");
		address_len = 12;
		break;
	case 0x21:
		printf("Protocol:\tTCP over IPv6\n");
		address_len = 36;
		break;
	case 0x22:
		printf("Protocol:\tUDP over IPv6\n");
		printf("ERROR:\tProtocol unsupported in hitch\n");
		address_len = 36;
		break;
	case 0x31:
		printf("Protocol:\tUNIX stream\n");
		address_len = 216;
		break;
	case 0x32:
		printf("Protocol:\tUNIX datagram\n");
		printf("ERROR:\tProtocol unsupported in hitch\n");
		address_len = 216;
		break;
	default:
		printf("ERROR:\t14th byte has illegal value %d\n",
		    (int)proxy_header[13]);
		return (1);
	}
	int additional_len = (proxy_header[14] << 8) + proxy_header[15];
	if (additional_len < address_len) {
		printf("ERROR:\tThe the total header length %d does"
		    " not leave room for the addresses\n",
		    additional_len + 16);
		return (1);
	}
	if (additional_len + 16 > n) {
		printf("ERROR:\tToo few bytes was read; %zd\n", n);
		return (1);
	}
	if (address_len == 12)
		print_addr_with_ports(AF_INET, 4, proxy_header + 16);
	else if (address_len == 36)
		print_addr_with_ports(AF_INET6, 16, proxy_header + 16);
	else {
		printf("ERROR:\tPrinting of UNIX socket addresses"
		    " not implemented.\n");
	}
	if (address_len < additional_len)
		return print_extensions(proxy_header + 16 + address_len,
		    additional_len - address_len);
	return (0);
}
Beispiel #2
0
static int do_cli(int argc, char **argv) /* {{{ */
{
	int c;
	zend_file_handle file_handle;
	int behavior = PHP_MODE_STANDARD;
	char *reflection_what = NULL;
	volatile int request_started = 0;
	volatile int exit_status = 0;
	char *php_optarg = NULL, *orig_optarg = NULL;
	int php_optind = 1, orig_optind = 1;
	char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL;
	char *arg_free=NULL, **arg_excp=&arg_free;
	char *script_file=NULL, *translated_path = NULL;
	int interactive=0;
	int lineno = 0;
	const char *param_error=NULL;
	int hide_argv = 0;

	zend_try {

		CG(in_compilation) = 0; /* not initialized but needed for several options */

		while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
			switch (c) {

			case 'i': /* php info & quit */
				if (php_request_startup()==FAILURE) {
					goto err;
				}
				request_started = 1;
				php_print_info(0xFFFFFFFF);
				php_output_end_all();
				exit_status = (c == '?' && argc > 1 && !strchr(argv[1],  c));
				goto out;

			case 'v': /* show php version & quit */
				php_printf("PHP %s (%s) (built: %s %s) ( %s)\nCopyright (c) 1997-2016 The PHP Group\n%s",
					PHP_VERSION, cli_sapi_module.name, __DATE__, __TIME__,
#if ZTS
					"ZTS "
#else
					"NTS "
#endif
#if ZEND_DEBUG
					"DEBUG "
#endif
#ifdef HAVE_GCOV
					"GCOV "
#endif
					,
					get_zend_version()
				);
				sapi_deactivate();
				goto out;

			case 'm': /* list compiled in modules */
				if (php_request_startup()==FAILURE) {
					goto err;
				}
				request_started = 1;
				php_printf("[PHP Modules]\n");
				print_modules();
				php_printf("\n[Zend Modules]\n");
				print_extensions();
				php_printf("\n");
				php_output_end_all();
				exit_status=0;
				goto out;

			default:
				break;
			}
		}

		/* Set some CLI defaults */
		SG(options) |= SAPI_OPTION_NO_CHDIR;

		php_optind = orig_optind;
		php_optarg = orig_optarg;
		while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
			switch (c) {

			case 'a':	/* interactive mode */
				if (!interactive) {
					if (behavior != PHP_MODE_STANDARD) {
						param_error = param_mode_conflict;
						break;
					}

					interactive=1;
				}
				break;

			case 'C': /* don't chdir to the script directory */
				/* This is default so NOP */
				break;

			case 'F':
				if (behavior == PHP_MODE_PROCESS_STDIN) {
					if (exec_run || script_file) {
						param_error = "You can use -R or -F only once.\n";
						break;
					}
				} else if (behavior != PHP_MODE_STANDARD) {
					param_error = param_mode_conflict;
					break;
				}
				behavior=PHP_MODE_PROCESS_STDIN;
				script_file = php_optarg;
				break;

			case 'f': /* parse file */
				if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
					param_error = param_mode_conflict;
					break;
				} else if (script_file) {
					param_error = "You can use -f only once.\n";
					break;
				}
				script_file = php_optarg;
				break;

			case 'l': /* syntax check mode */
				if (behavior != PHP_MODE_STANDARD) {
					break;
				}
				behavior=PHP_MODE_LINT;
				break;

			case 'q': /* do not generate HTTP headers */
				/* This is default so NOP */
				break;

			case 'r': /* run code from command line */
				if (behavior == PHP_MODE_CLI_DIRECT) {
					if (exec_direct || script_file) {
						param_error = "You can use -r only once.\n";
						break;
					}
				} else if (behavior != PHP_MODE_STANDARD || interactive) {
					param_error = param_mode_conflict;
					break;
				}
				behavior=PHP_MODE_CLI_DIRECT;
				exec_direct=php_optarg;
				break;

			case 'R':
				if (behavior == PHP_MODE_PROCESS_STDIN) {
					if (exec_run || script_file) {
						param_error = "You can use -R or -F only once.\n";
						break;
					}
				} else if (behavior != PHP_MODE_STANDARD) {
					param_error = param_mode_conflict;
					break;
				}
				behavior=PHP_MODE_PROCESS_STDIN;
				exec_run=php_optarg;
				break;

			case 'B':
				if (behavior == PHP_MODE_PROCESS_STDIN) {
					if (exec_begin) {
						param_error = "You can use -B only once.\n";
						break;
					}
				} else if (behavior != PHP_MODE_STANDARD || interactive) {
					param_error = param_mode_conflict;
					break;
				}
				behavior=PHP_MODE_PROCESS_STDIN;
				exec_begin=php_optarg;
				break;

			case 'E':
				if (behavior == PHP_MODE_PROCESS_STDIN) {
					if (exec_end) {
						param_error = "You can use -E only once.\n";
						break;
					}
				} else if (behavior != PHP_MODE_STANDARD || interactive) {
					param_error = param_mode_conflict;
					break;
				}
				behavior=PHP_MODE_PROCESS_STDIN;
				exec_end=php_optarg;
				break;

			case 's': /* generate highlighted HTML from source */
				if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
					param_error = "Source highlighting only works for files.\n";
					break;
				}
				behavior=PHP_MODE_HIGHLIGHT;
				break;

			case 'w':
				if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
					param_error = "Source stripping only works for files.\n";
					break;
				}
				behavior=PHP_MODE_STRIP;
				break;

			case 'z': /* load extension file */
				zend_load_extension(php_optarg);
				break;
			case 'H':
				hide_argv = 1;
				break;
			case 10:
				behavior=PHP_MODE_REFLECTION_FUNCTION;
				reflection_what = php_optarg;
				break;
			case 11:
				behavior=PHP_MODE_REFLECTION_CLASS;
				reflection_what = php_optarg;
				break;
			case 12:
				behavior=PHP_MODE_REFLECTION_EXTENSION;
				reflection_what = php_optarg;
				break;
			case 13:
				behavior=PHP_MODE_REFLECTION_ZEND_EXTENSION;
				reflection_what = php_optarg;
				break;
			case 14:
				behavior=PHP_MODE_REFLECTION_EXT_INFO;
				reflection_what = php_optarg;
				break;
			case 15:
				behavior = PHP_MODE_SHOW_INI_CONFIG;
				break;
			default:
				break;
			}
		}

		if (param_error) {
			PUTS(param_error);
			exit_status=1;
			goto err;
		}

		if (interactive) {
#if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
			printf("Interactive shell\n\n");
#else
			printf("Interactive mode enabled\n\n");
#endif
			fflush(stdout);
		}

		/* only set script_file if not set already and not in direct mode and not at end of parameter list */
		if (argc > php_optind
		  && !script_file
		  && behavior!=PHP_MODE_CLI_DIRECT
		  && behavior!=PHP_MODE_PROCESS_STDIN
		  && strcmp(argv[php_optind-1],"--"))
		{
			script_file=argv[php_optind];
			php_optind++;
		}
		if (script_file) {
			if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) {
				goto err;
			} else {
				char real_path[MAXPATHLEN];
				if (VCWD_REALPATH(script_file, real_path)) {
					translated_path = strdup(real_path);
				}
				script_filename = script_file;
			}
		} else {
			/* We could handle PHP_MODE_PROCESS_STDIN in a different manner  */
			/* here but this would make things only more complicated. And it */
			/* is consitent with the way -R works where the stdin file handle*/
			/* is also accessible. */
			file_handle.filename = "-";
			file_handle.handle.fp = stdin;
		}
		file_handle.type = ZEND_HANDLE_FP;
		file_handle.opened_path = NULL;
		file_handle.free_filename = 0;
		php_self = (char*)file_handle.filename;

		/* before registering argv to module exchange the *new* argv[0] */
		/* we can achieve this without allocating more memory */
		SG(request_info).argc=argc-php_optind+1;
		arg_excp = argv+php_optind-1;
		arg_free = argv[php_optind-1];
		SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename;
		argv[php_optind-1] = (char*)file_handle.filename;
		SG(request_info).argv=argv+php_optind-1;

		if (php_request_startup()==FAILURE) {
			*arg_excp = arg_free;
			fclose(file_handle.handle.fp);
			PUTS("Could not startup.\n");
			goto err;
		}
		request_started = 1;
		CG(start_lineno) = lineno;
		*arg_excp = arg_free; /* reconstuct argv */

		if (hide_argv) {
			int i;
			for (i = 1; i < argc; i++) {
				memset(argv[i], 0, strlen(argv[i]));
			}
		}

		zend_is_auto_global_str(ZEND_STRL("_SERVER"));

		PG(during_request_startup) = 0;
		switch (behavior) {
		case PHP_MODE_STANDARD:
			if (strcmp(file_handle.filename, "-")) {
				cli_register_file_handles();
			}

			if (interactive && cli_shell_callbacks.cli_shell_run) {
				exit_status = cli_shell_callbacks.cli_shell_run();
			} else {
				php_execute_script(&file_handle);
				exit_status = EG(exit_status);
			}
			break;
		case PHP_MODE_LINT:
			exit_status = php_lint_script(&file_handle);
			if (exit_status==SUCCESS) {
				zend_printf("No syntax errors detected in %s\n", file_handle.filename);
			} else {
				zend_printf("Errors parsing %s\n", file_handle.filename);
			}
			break;
		case PHP_MODE_STRIP:
			if (open_file_for_scanning(&file_handle)==SUCCESS) {
				zend_strip();
			}
			goto out;
			break;
		case PHP_MODE_HIGHLIGHT:
			{
				zend_syntax_highlighter_ini syntax_highlighter_ini;

				if (open_file_for_scanning(&file_handle)==SUCCESS) {
					php_get_highlight_struct(&syntax_highlighter_ini);
					zend_highlight(&syntax_highlighter_ini);
				}
				goto out;
			}
			break;
		case PHP_MODE_CLI_DIRECT:
			cli_register_file_handles();
			if (zend_eval_string_ex(exec_direct, NULL, "Command line code", 1) == FAILURE) {
				exit_status=254;
			}
			break;

		case PHP_MODE_PROCESS_STDIN:
			{
				char *input;
				size_t len, index = 0;
				zval argn, argi;

				cli_register_file_handles();

				if (exec_begin && zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1) == FAILURE) {
					exit_status=254;
				}
				while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
					len = strlen(input);
					while (len > 0 && len-- && (input[len]=='\n' || input[len]=='\r')) {
						input[len] = '\0';
					}
					ZVAL_STRINGL(&argn, input, len + 1);
					zend_hash_str_update(&EG(symbol_table), "argn", sizeof("argn")-1, &argn);
					ZVAL_LONG(&argi, ++index);
					zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi);
					if (exec_run) {
						if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) {
							exit_status=254;
						}
					} else {
						if (script_file) {
							if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) {
								exit_status = 1;
							} else {
								CG(start_lineno) = lineno;
								php_execute_script(&file_handle);
								exit_status = EG(exit_status);
							}
						}
					}
					efree(input);
				}
				if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) {
					exit_status=254;
				}

				break;
			}

			case PHP_MODE_REFLECTION_FUNCTION:
			case PHP_MODE_REFLECTION_CLASS:
			case PHP_MODE_REFLECTION_EXTENSION:
			case PHP_MODE_REFLECTION_ZEND_EXTENSION:
				{
					zend_class_entry *pce = NULL;
					zval arg, ref;
					zend_execute_data execute_data;

					switch (behavior) {
						default:
							break;
						case PHP_MODE_REFLECTION_FUNCTION:
							if (strstr(reflection_what, "::")) {
								pce = reflection_method_ptr;
							} else {
								pce = reflection_function_ptr;
							}
							break;
						case PHP_MODE_REFLECTION_CLASS:
							pce = reflection_class_ptr;
							break;
						case PHP_MODE_REFLECTION_EXTENSION:
							pce = reflection_extension_ptr;
							break;
						case PHP_MODE_REFLECTION_ZEND_EXTENSION:
							pce = reflection_zend_extension_ptr;
							break;
					}

					ZVAL_STRING(&arg, reflection_what);
					object_init_ex(&ref, pce);

					memset(&execute_data, 0, sizeof(zend_execute_data));
					EG(current_execute_data) = &execute_data;
					zend_call_method_with_1_params(&ref, pce, &pce->constructor, "__construct", NULL, &arg);

					if (EG(exception)) {
						zval tmp, *msg, rv;

						ZVAL_OBJ(&tmp, EG(exception));
						msg = zend_read_property(zend_ce_exception, &tmp, "message", sizeof("message")-1, 0, &rv);
						zend_printf("Exception: %s\n", Z_STRVAL_P(msg));
						zval_ptr_dtor(&tmp);
						EG(exception) = NULL;
					} else {
						zend_call_method_with_1_params(NULL, reflection_ptr, NULL, "export", NULL, &ref);
					}
					zval_ptr_dtor(&ref);
					zval_ptr_dtor(&arg);

					break;
				}
			case PHP_MODE_REFLECTION_EXT_INFO:
				{
					int len = (int)strlen(reflection_what);
					char *lcname = zend_str_tolower_dup(reflection_what, len);
					zend_module_entry *module;

					if ((module = zend_hash_str_find_ptr(&module_registry, lcname, len)) == NULL) {
						if (!strcmp(reflection_what, "main")) {
							display_ini_entries(NULL);
						} else {
							zend_printf("Extension '%s' not present.\n", reflection_what);
							exit_status = 1;
						}
					} else {
						php_info_print_module(module);
					}

					efree(lcname);
					break;
				}

			case PHP_MODE_SHOW_INI_CONFIG:
				{
					zend_printf("Configuration File (php.ini) Path: %s\n", PHP_CONFIG_FILE_PATH);
					zend_printf("Loaded Configuration File:         %s\n", php_ini_opened_path ? php_ini_opened_path : "(none)");
					zend_printf("Scan for additional .ini files in: %s\n", php_ini_scanned_path  ? php_ini_scanned_path : "(none)");
					zend_printf("Additional .ini files parsed:      %s\n", php_ini_scanned_files ? php_ini_scanned_files : "(none)");
					break;
				}
		}
	} zend_end_try();

out:
	if (request_started) {
		php_request_shutdown((void *) 0);
	}
	if (translated_path) {
		free(translated_path);
	}
	if (exit_status == 0) {
		exit_status = EG(exit_status);
	}
	return exit_status;
err:
	sapi_deactivate();
	zend_ini_deactivate();
	exit_status = 1;
	goto out;
}
Beispiel #3
0
/* _al_ogl_manage_extensions:
 * This functions fills the extensions API table and extension list
 * structures and displays on the log file which extensions are available.
 */
void _al_ogl_manage_extensions(ALLEGRO_DISPLAY *gl_disp)
{
    //const GLubyte *buf;
#if defined ALLEGRO_MACOSX
    CFURLRef bundle_url;
#endif
    ALLEGRO_OGL_EXT_API *ext_api;
    ALLEGRO_OGL_EXT_LIST *ext_list;

    /* Print out OpenGL extensions
     * We should use glGetStringi(GL_EXTENSIONS, i) for OpenGL 3.0+
     * but it doesn't seem to work until later.
     */
    if (!_al_ogl_version_3_only(gl_disp->flags)) {
        ALLEGRO_DEBUG("OpenGL Extensions:\n");
        print_extensions((char const *)glGetString(GL_EXTENSIONS));
    }

    /* Print out GLU version */
    //buf = gluGetString(GLU_VERSION);
    //ALLEGRO_INFO("GLU Version : %s\n", buf);

#ifdef ALLEGRO_HAVE_DYNAMIC_LINK
    /* Get glXGetProcAddress entry */
    __libgl_handle = dlopen("libGL.so", RTLD_LAZY);
    if (__libgl_handle) {
        alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle,
                            "glXGetProcAddressARB");
        if (!alXGetProcAddress) {
            alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle,
                                "glXGetProcAddress");
            if (!alXGetProcAddress) {
                alXGetProcAddress = (GLXGETPROCADDRESSARBPROC) dlsym(__libgl_handle,
                                    "eglGetProcAddress");
            }
        }
    }
    else {
        ALLEGRO_WARN("Failed to dlopen libGL.so : %s\n", dlerror());
    }
    ALLEGRO_INFO("glXGetProcAddress Extension: %s\n",
                 alXGetProcAddress ? "Supported" : "Unsupported");
#elif defined ALLEGRO_UNIX
#ifdef ALLEGROGL_GLXGETPROCADDRESSARB
    ALLEGRO_INFO("glXGetProcAddressARB Extension: supported\n");
#else
    ALLEGRO_INFO("glXGetProcAddress Extension: supported\n");
#endif
#endif

#ifdef ALLEGRO_MACOSX
    bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
                 CFSTR
                 ("/System/Library/Frameworks/OpenGL.framework"),
                 kCFURLPOSIXPathStyle, true);
    opengl_bundle_ref = CFBundleCreate(kCFAllocatorDefault, bundle_url);
    CFRelease(bundle_url);
#endif

#if defined ALLEGRO_UNIX && !defined ALLEGRO_EXCLUDE_GLX
    ALLEGRO_DEBUG("GLX Extensions:\n");
    ALLEGRO_SYSTEM_XGLX *glx_sys = (void*)al_get_system_driver();
    ALLEGRO_DISPLAY_XGLX *glx_disp = (void *)gl_disp;
    char const *ext = glXQueryExtensionsString(
                          glx_sys->gfxdisplay, glx_disp->xscreen);
    if (!ext) {
        /* work around driver bugs? */
        ext = "";
    }
    print_extensions(ext);
#endif

    fill_in_info_struct(glGetString(GL_RENDERER), &(gl_disp->ogl_extras->ogl_info));

    /* Create & load extension API table */
    ext_api = create_extension_api_table();
    load_extensions(ext_api);
    gl_disp->ogl_extras->extension_api = ext_api;

#if !defined ALLEGRO_IPHONE && !defined ALLEGRO_ANDROID
    /* Need that symbol already so can't wait until it is assigned later. */
    glGetStringi = ext_api->GetStringi;

    if (_al_ogl_version_3_only(gl_disp->flags)) {
        ALLEGRO_DEBUG("OpenGL Extensions:\n");
        print_extensions_3_0();
    }
#endif

    /* Create the list of supported extensions. */
    ext_list = create_extension_list();
    gl_disp->ogl_extras->extension_list = ext_list;

    /* Fill the list. */
#define AGL_EXT(name, ver) { \
      ext_list->ALLEGRO_GL_##name = \
         _ogl_is_extension_with_version_supported("GL_" #name, gl_disp, \
            _ALLEGRO_OPENGL_VERSION_##ver); \
   }
#include "allegro5/opengl/GLext/gl_ext_list.h"
#undef AGL_EXT

#ifdef ALLEGRO_UNIX
#define AGL_EXT(name, ver) { \
      ext_list->ALLEGRO_GLX_##name = \
         _ogl_is_extension_with_version_supported("GLX_" #name, gl_disp, \
            _ALLEGRO_OPENGL_VERSION_##ver); \
   }
#include "allegro5/opengl/GLext/glx_ext_list.h"
#undef AGL_EXT
#elif defined ALLEGRO_WINDOWS
#define AGL_EXT(name, ver) { \
      ext_list->ALLEGRO_WGL_##name = \
         _ogl_is_extension_with_version_supported("WGL_" #name, gl_disp, \
            _ALLEGRO_OPENGL_VERSION_##ver); \
   }
#include "allegro5/opengl/GLext/wgl_ext_list.h"
#undef AGL_EXT
#endif

    /* TODO: use these somewhere */
#if 0
    for (i = 0; i < 5; i++) {
        __allegro_gl_texture_read_format[i] = -1;
        __allegro_gl_texture_components[i] = GL_RGB;
    }
    __allegro_gl_texture_read_format[3] = GL_UNSIGNED_BYTE;
    __allegro_gl_texture_read_format[4] = GL_UNSIGNED_BYTE;
    __allegro_gl_texture_components[4] = GL_RGBA;
#endif /* #if 0 */

    /* Get max texture size */
    glGetIntegerv(GL_MAX_TEXTURE_SIZE,
                  (GLint *) & gl_disp->ogl_extras->ogl_info.max_texture_size);

    /* Note: Voodoo (even V5) don't seem to correctly support
     * packed pixel formats. Disabling them for those cards.
     */
    ext_list->ALLEGRO_GL_EXT_packed_pixels &= !gl_disp->ogl_extras->ogl_info.is_voodoo;


    if (ext_list->ALLEGRO_GL_EXT_packed_pixels) {

        ALLEGRO_INFO("Packed Pixels formats available\n");

        /* XXX On NV cards, we want to use BGRA instead of RGBA for speed */
        /* Fills the __allegro_gl_texture_format array */
        /* TODO: use these somewhere */
#if 0
        __allegro_gl_texture_read_format[0] = GL_UNSIGNED_BYTE_3_3_2;
        __allegro_gl_texture_read_format[1] = GL_UNSIGNED_SHORT_5_5_5_1;
        __allegro_gl_texture_read_format[2] = GL_UNSIGNED_SHORT_5_6_5;
#endif /* #if 0 */
    }

    /* NVidia and ATI cards expose OpenGL 2.0 but often don't accelerate
     * non-power-of-2 textures. This check is how you verify that NP2
     * textures are hardware accelerated or not.
     * We should clobber the NPOT support if it's not accelerated.
     */
    {
        const char *vendor = (const char *)glGetString(GL_VENDOR);
        if (strstr(vendor, "NVIDIA Corporation")) {
            if (!ext_list->ALLEGRO_GL_NV_fragment_program2
                    || !ext_list->ALLEGRO_GL_NV_vertex_program3) {
                ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0;
            }
        }
        else if (strstr(vendor, "ATI Technologies")) {
            if (_al_ogl_version_3_only(gl_disp->flags)) {
                /* Assume okay. */
            }
            else if (!strstr((const char *)glGetString(GL_EXTENSIONS),
                             "GL_ARB_texture_non_power_of_two")
                     && gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) {
                ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two = 0;
            }
        }
    }

    {
        int *s = gl_disp->extra_settings.settings;
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, s + ALLEGRO_MAX_BITMAP_SIZE);

        if (gl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0)
            s[ALLEGRO_SUPPORT_SEPARATE_ALPHA] = 1;

        s[ALLEGRO_SUPPORT_NPOT_BITMAP] =
            ext_list->ALLEGRO_GL_ARB_texture_non_power_of_two ||
            ext_list->ALLEGRO_GL_OES_texture_npot;
        ALLEGRO_INFO("Use of non-power-of-two textures %s.\n",
                     s[ALLEGRO_SUPPORT_NPOT_BITMAP] ? "enabled" : "disabled");
#if defined ALLEGRO_IPHONE || defined ALLEGRO_ANDROID
        if (gl_disp->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
            s[ALLEGRO_CAN_DRAW_INTO_BITMAP] = true;
        }
        else {
            s[ALLEGRO_CAN_DRAW_INTO_BITMAP] =
                ext_list->ALLEGRO_GL_OES_framebuffer_object;
        }
        ALLEGRO_INFO("Use of FBO to draw to textures %s.\n",
                     s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" :
                     "disabled");
#else
        s[ALLEGRO_CAN_DRAW_INTO_BITMAP] =
            ext_list->ALLEGRO_GL_EXT_framebuffer_object;
        ALLEGRO_INFO("Use of FBO to draw to textures %s.\n",
                     s[ALLEGRO_CAN_DRAW_INTO_BITMAP] ? "enabled" :
                     "disabled");
#endif
    }
}