summaryrefslogtreecommitdiff
path: root/src/update.c
diff options
context:
space:
mode:
authorJoJoBond <jojobond@hotmail.com>2010-11-05 21:28:04 (GMT)
committer JoJoBond <jojobond@hotmail.com>2010-11-05 21:28:04 (GMT)
commit891774a7e2935a2e82eba8dd51a8f9782b407149 (patch)
tree75399c741be7486e42e88d4d5c88089a4ceb9c2d /src/update.c
parent9b8acd9259f67c9efa8125538c91b6108e4155d3 (diff)
parent6124922b9f47003e4935580d792b7ba3b8ba1ede (diff)
downloadpowder-891774a7e2935a2e82eba8dd51a8f9782b407149.zip
powder-891774a7e2935a2e82eba8dd51a8f9782b407149.tar.gz
Merge branch 'master' of github.com:JoJoBond/The-Powder-Toy
Diffstat (limited to 'src/update.c')
-rw-r--r--src/update.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/update.c b/src/update.c
new file mode 100644
index 0000000..99b9d1b
--- /dev/null
+++ b/src/update.c
@@ -0,0 +1,201 @@
+/**
+ * Powder Toy - Update Helper
+ *
+ * Copyright (c) 2008 - 2010 Stanislaw Skowronek.
+ * Copyright (c) 2010 Simon Robertshaw
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include <stdio.h>
+#ifndef MACOSX
+#include <malloc.h>
+#endif
+#include <string.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/stat.h>
+#endif
+#ifdef MACOSX
+#include <mach-o/dyld.h>
+#include <errno.h>
+#include <sys/param.h>
+#endif
+
+#include <update.h>
+
+static char *exe_name(void)
+{
+#if defined WIN32
+ char *name= (char *)malloc(64), max=64, res;
+ while((res = (char)GetModuleFileName(NULL, name, max)) >= max)
+ {
+#elif defined MACOSX
+ char *fn=malloc(64),*name=malloc(PATH_MAX), max=64, res;
+ if(_NSGetExecutablePath(fn, &max) != 0)
+ {
+ fn = realloc(fn, max);
+ _NSGetExecutablePath(fn, &max);
+ }
+ if(realpath(fn, name) == NULL)
+ {
+ free(fn);
+ free(name);
+ return NULL;
+ }
+ res = 1;
+#else
+ char fn[64], *name=malloc(64), max=64, res;
+ sprintf(fn, "/proc/self/exe");
+ memset(name, 0, max);
+ while((res = readlink(fn, name, max)) >= max-1)
+ {
+#endif
+#ifndef MACOSX
+ max *= 2;
+ name = realloc(name, max);
+ memset(name, 0, max);
+ }
+#endif
+ if(res <= 0)
+ {
+ free(name);
+ return NULL;
+ }
+ return name;
+}
+
+int update_start(char *data, int len)
+{
+ char *self=exe_name(), *temp;
+#ifdef WIN32
+ char *p;
+#endif
+ FILE *f;
+ int res = 1;
+
+ if(!self)
+ return 1;
+
+#ifdef WIN32
+ temp = malloc(strlen(self)+12);
+ strcpy(temp, self);
+ p = temp + strlen(temp) - 4;
+ if(_stricmp(p, ".exe"))
+ p += 4;
+ strcpy(p, "_update.exe");
+
+ if(!MoveFile(self, temp))
+ goto fail;
+
+ f = fopen(self, "wb");
+ if(!f)
+ goto fail;
+ if(fwrite(data, 1, len, f) != len)
+ {
+ fclose(f);
+ DeleteFile(self);
+ goto fail;
+ }
+ fclose(f);
+
+ if((int)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32)
+ {
+ DeleteFile(self);
+ goto fail;
+ }
+
+ return 0;
+#else
+ temp = malloc(strlen(self)+8);
+ strcpy(temp, self);
+ strcat(temp, "-update");
+
+ f = fopen(temp, "w");
+ if(!f)
+ goto fail;
+ if(fwrite(data, 1, len, f) != len)
+ {
+ fclose(f);
+ unlink(temp);
+ goto fail;
+ }
+ fclose(f);
+
+ if(chmod(temp, 0755))
+ {
+ unlink(temp);
+ goto fail;
+ }
+
+ if(rename(temp, self))
+ {
+ unlink(temp);
+ goto fail;
+ }
+
+ execl(self, "powder-update", NULL);
+#endif
+
+fail:
+ free(temp);
+ free(self);
+ return res;
+}
+
+int update_finish(void)
+{
+#ifdef WIN32
+ char *temp, *self=exe_name(), *p;
+ int timeout = 60, err;
+
+ temp = malloc(strlen(self)+12);
+ strcpy(temp, self);
+ p = temp + strlen(temp) - 4;
+ if(_stricmp(p, ".exe"))
+ p += 4;
+ strcpy(p, "_update.exe");
+
+ while(!DeleteFile(temp))
+ {
+ err = GetLastError();
+ if(err == ERROR_FILE_NOT_FOUND)
+ {
+ // just as well, then
+ free(temp);
+ return 0;
+ }
+ Sleep(500);
+ timeout--;
+ if(timeout <= 0)
+ {
+ free(temp);
+ return 1;
+ }
+ }
+ free(temp);
+#endif
+ return 0;
+}
+
+void update_cleanup(void)
+{
+#ifdef WIN32
+ update_finish();
+#endif
+}