[Python-checkins] python/dist/src/PC/bdist_wininst install.c, 1.1, 1.2

theller at users.sourceforge.net theller at users.sourceforge.net
Fri Feb 20 09:43:24 EST 2004


Update of /cvsroot/python/python/dist/src/PC/bdist_wininst
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28252
Modified Files:
	install.c 
Log Message:
Patch #892660 from Mark Hammond, for distutils bdist_wininst command.
install.c: support for a 'pre-install-script', run before anything has
been installed. Provides a 'message_box' module function for use by
either the pre-install or post-install scripts.
bdist_wininst.py: support for pre-install script. Typo (build->built),
fixes so that --target-version can still work, even when the
distribution has extension modules - in this case, we insist on
--skip-build, as we still can't actually build other versions.
Index: install.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/PC/bdist_wininst/install.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** install.c	22 Nov 2002 20:39:33 -0000	1.1
--- install.c	20 Feb 2004 14:43:21 -0000	1.2
***************
*** 118,121 ****
--- 118,122 ----
 				 'Distutils' */
 char install_script[MAX_PATH];
+ char *pre_install_script; /* run before we install a single file */
 
 
***************
*** 130,133 ****
--- 131,135 ----
 
 BOOL success;			/* Installation successfull? */
+ char *failure_reason = NULL;
 
 HANDLE hBitmap;
***************
*** 207,210 ****
--- 209,226 ----
 } *file_list = NULL;
 
+ static void set_failure_reason(char *reason)
+ {
+ if (failure_reason)
+ 	free(failure_reason);
+ failure_reason = strdup(reason);
+ success = FALSE;
+ }
+ static char *get_failure_reason()
+ {
+ if (!failure_reason)
+ 	return "Installation failed.";
+ return failure_reason;
+ }
+ 
 static void add_to_filelist(char *path)
 {
***************
*** 533,537 ****
 	if (FAILED(hr)) {
 		g_PyErr_Format(g_PyExc_OSError,
! 			 "Save() failed, error 0x%x", hr);
 		goto error;
 	}
--- 549,553 ----
 	if (FAILED(hr)) {
 		g_PyErr_Format(g_PyExc_OSError,
! 			 "Failed to create shortcut '%s' - error 0x%x", filename, hr);
 		goto error;
 	}
***************
*** 554,557 ****
--- 570,584 ----
 }
 
+ static PyObject *PyMessageBox(PyObject *self, PyObject *args)
+ {
+ 	int rc;
+ 	char *text, *caption;
+ 	int flags;
+ 	if (!g_PyArg_ParseTuple(args, "ssi", &text, &caption, &flags))
+ 		return NULL;
+ 	rc = MessageBox(GetFocus(), text, caption, flags);
+ 	return g_Py_BuildValue("i", rc);
+ }
+ 
 #define METH_VARARGS 0x0001
 
***************
*** 561,566 ****
--- 588,627 ----
 	{"file_created", FileCreated, METH_VARARGS, NULL},
 	{"directory_created", DirectoryCreated, METH_VARARGS, NULL},
+ 	{"message_box", PyMessageBox, METH_VARARGS, NULL},
 };
 
+ static int prepare_script_environment(HINSTANCE hPython)
+ {
+ 	PyObject *mod;
+ 	DECLPROC(hPython, PyObject *, PyImport_ImportModule, (char *));
+ 	DECLPROC(hPython, int, PyObject_SetAttrString, (PyObject *, char *, PyObject *));
+ 	DECLPROC(hPython, PyObject *, PyObject_GetAttrString, (PyObject *, char *));
+ 	DECLPROC(hPython, PyObject *, PyCFunction_New, (PyMethodDef *, PyObject *));
+ 	DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
+ 	DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
+ 	DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
+ 	if (!PyImport_ImportModule || !PyObject_GetAttrString || 
+ 	 !PyObject_SetAttrString || !PyCFunction_New)
+ 		return 1;
+ 	if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
+ 		return 1;
+ 
+ 	mod = PyImport_ImportModule("__builtin__");
+ 	if (mod) {
+ 		int i;
+ 		g_PyExc_ValueError = PyObject_GetAttrString(mod, "ValueError");
+ 		g_PyExc_OSError = PyObject_GetAttrString(mod, "OSError");
+ 		for (i = 0; i < DIM(meth); ++i) {
+ 			PyObject_SetAttrString(mod, meth[i].ml_name,
+ 					 PyCFunction_New(&meth[i], NULL));
+ 		}
+ 	}
+ 	g_Py_BuildValue = Py_BuildValue;
+ 	g_PyArg_ParseTuple = PyArg_ParseTuple;
+ 	g_PyErr_Format = PyErr_Format;
+ 
+ 	return 0;
+ }
+ 
 /*
 * This function returns one of the following error codes:
***************
*** 580,588 ****
 	DECLPROC(hPython, int, PyRun_SimpleFile, (FILE *, char *));
 	DECLPROC(hPython, void, Py_Finalize, (void));
- 	DECLPROC(hPython, PyObject *, PyImport_ImportModule, (char *));
- 	DECLPROC(hPython, int, PyObject_SetAttrString,
- 		 (PyObject *, char *, PyObject *));
- 	DECLPROC(hPython, PyObject *, PyObject_GetAttrString,
- 		 (PyObject *, char *));
 	DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
 	DECLPROC(hPython, PyObject *, PyCFunction_New,
--- 641,644 ----
***************
*** 591,596 ****
 	DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
 
- 	PyObject *mod;
- 
 	int result = 0;
 	FILE *fp;
--- 647,650 ----
***************
*** 600,605 ****
 		return 1;
 	
! 	if (!PyImport_ImportModule || !PyObject_SetAttrString
! 	 || !Py_BuildValue)
 		return 1;
 
--- 654,658 ----
 		return 1;
 	
! 	if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format)
 		return 1;
 
***************
*** 607,617 ****
 		return 1;
 
- 	if (!PyObject_GetAttrString)
- 		return 1;
- 
- 	g_Py_BuildValue = Py_BuildValue;
- 	g_PyArg_ParseTuple = PyArg_ParseTuple;
- 	g_PyErr_Format = PyErr_Format;
- 
 	if (pathname == NULL || pathname[0] == '0円')
 		return 2;
--- 660,663 ----
***************
*** 628,644 ****
 	Py_Initialize();
 
! 	mod = PyImport_ImportModule("__builtin__");
! 	if (mod) {
! 		int i;
! 
! 		g_PyExc_ValueError = PyObject_GetAttrString(mod,
! 							 "ValueError");
! 		g_PyExc_OSError = PyObject_GetAttrString(mod, "OSError");
! 		for (i = 0; i < DIM(meth); ++i) {
! 			PyObject_SetAttrString(mod, meth[i].ml_name,
! 					 PyCFunction_New(&meth[i], NULL));
! 		}
! 	}
! 
 	PySys_SetArgv(argc, argv);
 	result = PyRun_SimpleFile(fp, pathname);
--- 674,678 ----
 	Py_Initialize();
 
! 	prepare_script_environment(hPython);
 	PySys_SetArgv(argc, argv);
 	result = PyRun_SimpleFile(fp, pathname);
***************
*** 650,653 ****
--- 684,758 ----
 }
 
+ static int do_run_simple_script(HINSTANCE hPython, char *script)
+ {
+ 	int rc;
+ 	DECLPROC(hPython, void, Py_Initialize, (void));
+ 	DECLPROC(hPython, void, Py_SetProgramName, (char *));
+ 	DECLPROC(hPython, void, Py_Finalize, (void));
+ 	DECLPROC(hPython, int, PyRun_SimpleString, (char *));
+ 	DECLPROC(hPython, void, PyErr_Print, (void));
+ 
+ 	if (!Py_Initialize || !Py_SetProgramName || !Py_Finalize || 
+ 	 !PyRun_SimpleString || !PyErr_Print)
+ 		return -1;
+ 
+ 	Py_SetProgramName(modulename);
+ 	Py_Initialize();
+ 	prepare_script_environment(hPython);
+ 	rc = PyRun_SimpleString(script);
+ 	if (rc)
+ 		PyErr_Print();
+ 	Py_Finalize();
+ 	return rc;
+ }
+ 
+ static int run_simple_script(char *script)
+ {
+ 	int rc;
+ 	char *tempname;
+ 	HINSTANCE hPython;
+ 	tempname = tmpnam(NULL);
+ 	freopen(tempname, "a", stderr);
+ 	freopen(tempname, "a", stdout);
+ 
+ 	hPython = LoadLibrary (pythondll);
+ 	if (!hPython) {
+ 		set_failure_reason("Can't load Python for pre-install script");
+ 		return -1;
+ 	}
+ 	rc = do_run_simple_script(hPython, script);
+ 	FreeLibrary(hPython);
+ 	fflush(stderr);
+ 	fflush(stdout);
+ 	/* We only care about the output when we fail. If the script works
+ 	 OK, then we discard it
+ 	*/
+ 	if (rc) {
+ 		int err_buf_size;
+ 		char *err_buf;
+ 		const char *prefix = "Running the pre-installation script failed\r\n";
+ 		int prefix_len = strlen(prefix);
+ 		FILE *fp = fopen(tempname, "rb");
+ 		fseek(fp, 0, SEEK_END);
+ 		err_buf_size = ftell(fp);
+ 		fseek(fp, 0, SEEK_SET);
+ 		err_buf = malloc(prefix_len + err_buf_size + 1);
+ 		if (err_buf) {
+ 			int n;
+ 			strcpy(err_buf, prefix);
+ 			n = fread(err_buf+prefix_len, 1, err_buf_size, fp);
+ 			err_buf[prefix_len+n] = '0円';
+ 			fclose(fp);
+ 			set_failure_reason(err_buf);
+ 			free(err_buf);
+ 		} else {
+ 			set_failure_reason("Out of memory!");
+ 		}
+ 	}
+ 	remove(tempname);
+ 	return rc;
+ }
+ 
+ 
 static BOOL SystemError(int error, char *msg)
 {
***************
*** 812,816 ****
 }
 
! static char *ExtractIniFile(char *data, DWORD size, int *pexe_size)
 {
 	/* read the end of central directory record */
--- 917,925 ----
 }
 
! /* Extract everything we need to begin the installation. Currently this
! is the INI filename with install data, and the raw pre-install script
! */
! static BOOL ExtractInstallData(char *data, DWORD size, int *pexe_size,
! 			 char **out_ini_file, char **out_preinstall_script)
 {
 	/* read the end of central directory record */
***************
*** 829,838 ****
 	char tempdir[MAX_PATH];
 
 	if (pe->tag != 0x06054b50) {
! 		return NULL;
 	}
 
 	if (pmd->tag != 0x1234567A || ofs < 0) {
! 		return NULL;
 	}
 
--- 938,950 ----
 	char tempdir[MAX_PATH];
 
+ 	/* ensure that if we fail, we don't have garbage out pointers */
+ 	*out_ini_file = *out_preinstall_script = NULL;
+ 
 	if (pe->tag != 0x06054b50) {
! 		return FALSE;
 	}
 
 	if (pmd->tag != 0x1234567A || ofs < 0) {
! 		return FALSE;
 	}
 
***************
*** 847,856 ****
 	ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */
 	if (!ini_file)
! 		return NULL;
 	if (!GetTempPath(sizeof(tempdir), tempdir)
 	 || !GetTempFileName(tempdir, "~du", 0, ini_file)) {
 		SystemError(GetLastError(),
 			 "Could not create temporary file");
! 		return NULL;
 	}
 
--- 959,968 ----
 	ini_file = malloc(MAX_PATH); /* will be returned, so do not free it */
 	if (!ini_file)
! 		return FALSE;
 	if (!GetTempPath(sizeof(tempdir), tempdir)
 	 || !GetTempFileName(tempdir, "~du", 0, ini_file)) {
 		SystemError(GetLastError(),
 			 "Could not create temporary file");
! 		return FALSE;
 	}
 
***************
*** 858,865 ****
 			 0, 0, NULL/*notify*/);
 	if (!dst)
! 		return NULL;
! 	memcpy(dst, src, pmd->uncomp_size);
 	UnmapViewOfFile(dst);
! 	return ini_file;
 }
 
--- 970,982 ----
 			 0, 0, NULL/*notify*/);
 	if (!dst)
! 		return FALSE;
! 	/* Up to the first 0円 is the INI file data. */
! 	strncpy(dst, src, pmd->uncomp_size);
! 	src += strlen(dst) + 1;
! 	/* Up to next 0円 is the pre-install script */
! 	*out_preinstall_script = strdup(src);
! 	*out_ini_file = ini_file;
 	UnmapViewOfFile(dst);
! 	return TRUE;
 }
 
***************
*** 1355,1359 ****
 						if (result == 2)
 #ifdef _DEBUG
! 							wsprintf(pythondll, "c:\\python22\\PCBuild\\python%d%d_d.dll",
 								 py_major, py_minor);
 #else
--- 1472,1476 ----
 						if (result == 2)
 #ifdef _DEBUG
! 							wsprintf(pythondll, "python%d%d_d.dll",
 								 py_major, py_minor);
 #else
***************
*** 1543,1546 ****
--- 1660,1664 ----
 			 meta_name);
 		SetDlgItemText(hwnd, IDC_TITLE, Buffer);
+ 		SetDlgItemText(hwnd, IDC_INFO, "Ready to install");
 		break;
 
***************
*** 1572,1575 ****
--- 1690,1694 ----
 			/* Handle a Next button click here */
 			hDialog = hwnd;
+ 			success = TRUE;
 
 			/* Make sure the installation directory name ends in a */
***************
*** 1603,1614 ****
 */
 			scheme = GetScheme(py_major, py_minor);
! 
 			/* Extract all files from the archive */
 			SetDlgItemText(hwnd, IDC_TITLE, "Installing files...");
! 			success = unzip_archive(scheme,
! 						 python_dir, arc_data,
! 						 arc_size, notify);
 			/* Compile the py-files */
! 			if (pyc_compile) {
 				int errors;
 				HINSTANCE hPython;
--- 1722,1742 ----
 */
 			scheme = GetScheme(py_major, py_minor);
! 			/* Run the pre-install script. */
! 			if (pre_install_script && *pre_install_script) {
! 				SetDlgItemText (hwnd, IDC_TITLE,
! 						"Running pre-installation script");
! 				run_simple_script(pre_install_script);
! 			}
! 			if (!success) {
! 				break;
! 			}
 			/* Extract all files from the archive */
 			SetDlgItemText(hwnd, IDC_TITLE, "Installing files...");
! 			if (!unzip_archive (scheme,
! 					 python_dir, arc_data,
! 					 arc_size, notify))
! 				set_failure_reason("Failed to unzip installation files");
 			/* Compile the py-files */
! 			if (success && pyc_compile) {
 				int errors;
 				HINSTANCE hPython;
***************
*** 1629,1633 ****
 				 */
 			}
! 			if (pyo_compile) {
 				int errors;
 				HINSTANCE hPython;
--- 1757,1761 ----
 				 */
 			}
! 			if (success && pyo_compile) {
 				int errors;
 				HINSTANCE hPython;
***************
*** 1669,1673 ****
 					 IMAGE_BITMAP, (LPARAM)hBitmap);
 		if (!success)
! 			SetDlgItemText(hwnd, IDC_INFO, "Installation failed.");
 
 		/* async delay: will show the dialog box completely before
--- 1797,1801 ----
 					 IMAGE_BITMAP, (LPARAM)hBitmap);
 		if (!success)
! 			SetDlgItemText(hwnd, IDC_INFO, get_failure_reason());
 
 		/* async delay: will show the dialog box completely before
***************
*** 1678,1682 ****
 	case WM_USER:
 
! 		if (install_script && install_script[0]) {
 			char fname[MAX_PATH];
 			char *tempname;
--- 1806,1810 ----
 	case WM_USER:
 
! 		if (success && install_script && install_script[0]) {
 			char fname[MAX_PATH];
 			char *tempname;
***************
*** 2272,2278 ****
 
 	/* Try to extract the configuration data into a temporary file */
! 	ini_file = ExtractIniFile(arc_data, arc_size, &exe_size);
! 
! 	if (ini_file)
 		return DoInstall();
 
--- 2400,2405 ----
 
 	/* Try to extract the configuration data into a temporary file */
! 	if (ExtractInstallData(arc_data, arc_size, &exe_size,
! 			 &ini_file, &pre_install_script))
 		return DoInstall();
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /