diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-25 20:21:41 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-25 20:21:41 +0000 |
commit | 78d9ac52db47a21e2260ec82b6666ca014fc4c68 (patch) | |
tree | 7c513579fdb4dd2340d5ffe8e72f560467c74037 /app/smproxy/save.c | |
parent | 4009f4bb8e19be65985224de572a56c7e547ff62 (diff) |
Importing from X.Org 7.2RC2
Diffstat (limited to 'app/smproxy/save.c')
-rw-r--r-- | app/smproxy/save.c | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/app/smproxy/save.c b/app/smproxy/save.c new file mode 100644 index 000000000..e7061d7f6 --- /dev/null +++ b/app/smproxy/save.c @@ -0,0 +1,493 @@ +/* $Xorg: save.c,v 1.4 2001/02/09 02:05:35 xorgcvs Exp $ */ +/****************************************************************************** + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Ralph Mor, X Consortium +******************************************************************************/ +/* $XFree86: xc/programs/smproxy/save.c,v 1.7 2001/01/17 23:45:04 dawes Exp $ */ + +#include "smproxy.h" +#ifdef HAS_MKSTEMP +#include <unistd.h> +#endif + + +ProxyFileEntry *proxyFileHead = NULL; + +extern WinInfo *win_head; + +static int write_byte ( FILE *file, unsigned char b ); +static int write_short ( FILE *file, unsigned short s ); +static int write_counted_string ( FILE *file, char *string ); +static int read_byte ( FILE *file, unsigned char *bp ); +static int read_short ( FILE *file, unsigned short *shortp ); +static int read_counted_string ( FILE *file, char **stringp ); +#ifndef HAS_MKSTEMP +static char * unique_filename ( char *path, char *prefix ); +#else +static char * unique_filename ( char *path, char *prefix, int *pFd ); +#endif + + +static int +write_byte (FILE *file, unsigned char b) +{ + if (fwrite ((char *) &b, 1, 1, file) != 1) + return 0; + return 1; +} + + +static int +write_short (FILE *file, unsigned short s) +{ + unsigned char file_short[2]; + + file_short[0] = (s & (unsigned)0xff00) >> 8; + file_short[1] = s & 0xff; + if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) + return 0; + return 1; +} + + +static int +write_counted_string (file, string) + +FILE *file; +char *string; + +{ + if (string) + { + unsigned char count = strlen (string); + + if (write_byte (file, count) == 0) + return 0; + if (fwrite (string, (int) sizeof (char), (int) count, file) != count) + return 0; + } + else + { + if (write_byte (file, 0) == 0) + return 0; + } + + return 1; +} + + + +static int +read_byte (file, bp) + +FILE *file; +unsigned char *bp; + +{ + if (fread ((char *) bp, 1, 1, file) != 1) + return 0; + return 1; +} + + +static int +read_short (file, shortp) + +FILE *file; +unsigned short *shortp; + +{ + unsigned char file_short[2]; + + if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) + return 0; + *shortp = file_short[0] * 256 + file_short[1]; + return 1; +} + + +static int +read_counted_string (file, stringp) + +FILE *file; +char **stringp; + +{ + unsigned char len; + char *data; + + if (read_byte (file, &len) == 0) + return 0; + if (len == 0) { + data = 0; + } else { + data = (char *) malloc ((unsigned) len + 1); + if (!data) + return 0; + if (fread (data, (int) sizeof (char), (int) len, file) != len) { + free (data); + return 0; + } + data[len] = '\0'; + } + *stringp = data; + return 1; +} + + + +/* + * An entry in the .smproxy file looks like this: + * + * FIELD BYTES + * ----- ---- + * client ID len 1 + * client ID LIST of bytes + * WM_CLASS "res name" length 1 + * WM_CLASS "res name" LIST of bytes + * WM_CLASS "res class" length 1 + * WM_CLASS "res class" LIST of bytes + * WM_NAME length 1 + * WM_NAME LIST of bytes + * WM_COMMAND arg count 1 + * For each arg in WM_COMMAND + * arg length 1 + * arg LIST of bytes + */ + +int +WriteProxyFileEntry (proxyFile, theWindow) + +FILE *proxyFile; +WinInfo *theWindow; + +{ + int i; + + if (!write_counted_string (proxyFile, theWindow->client_id)) + return 0; + if (!write_counted_string (proxyFile, theWindow->class.res_name)) + return 0; + if (!write_counted_string (proxyFile, theWindow->class.res_class)) + return 0; + if (!write_counted_string (proxyFile, theWindow->wm_name)) + return 0; + + if (!theWindow->wm_command || theWindow->wm_command_count == 0) + { + if (!write_byte (proxyFile, 0)) + return 0; + } + else + { + if (!write_byte (proxyFile, (char) theWindow->wm_command_count)) + return 0; + for (i = 0; i < theWindow->wm_command_count; i++) + if (!write_counted_string (proxyFile, theWindow->wm_command[i])) + return 0; + } + + return 1; +} + + +int +ReadProxyFileEntry (proxyFile, pentry) + +FILE *proxyFile; +ProxyFileEntry **pentry; + +{ + ProxyFileEntry *entry; + unsigned char byte; + int i; + + *pentry = entry = (ProxyFileEntry *) malloc ( + sizeof (ProxyFileEntry)); + if (!*pentry) + return 0; + + entry->tag = 0; + entry->client_id = NULL; + entry->class.res_name = NULL; + entry->class.res_class = NULL; + entry->wm_name = NULL; + entry->wm_command = NULL; + entry->wm_command_count = 0; + + if (!read_counted_string (proxyFile, &entry->client_id)) + goto give_up; + if (!read_counted_string (proxyFile, &entry->class.res_name)) + goto give_up; + if (!read_counted_string (proxyFile, &entry->class.res_class)) + goto give_up; + if (!read_counted_string (proxyFile, &entry->wm_name)) + goto give_up; + + if (!read_byte (proxyFile, &byte)) + goto give_up; + entry->wm_command_count = byte; + + if (entry->wm_command_count == 0) + entry->wm_command = NULL; + else + { + entry->wm_command = (char **) malloc (entry->wm_command_count * + sizeof (char *)); + + if (!entry->wm_command) + goto give_up; + + for (i = 0; i < entry->wm_command_count; i++) + if (!read_counted_string (proxyFile, &entry->wm_command[i])) + goto give_up; + } + + return 1; + +give_up: + + if (entry->client_id) + free (entry->client_id); + if (entry->class.res_name) + free (entry->class.res_name); + if (entry->class.res_class) + free (entry->class.res_class); + if (entry->wm_name) + free (entry->wm_name); + if (entry->wm_command_count) + { + for (i = 0; i < entry->wm_command_count; i++) + if (entry->wm_command[i]) + free (entry->wm_command[i]); + } + if (entry->wm_command) + free ((char *) entry->wm_command); + + free ((char *) entry); + *pentry = NULL; + + return 0; +} + + +void +ReadProxyFile (filename) + +char *filename; + +{ + FILE *proxyFile; + ProxyFileEntry *entry; + int done = 0; + unsigned short version; + + proxyFile = fopen (filename, "rb"); + if (!proxyFile) + return; + + if (!read_short (proxyFile, &version) || + version > SAVEFILE_VERSION) + { + done = 1; + } + + while (!done) + { + if (ReadProxyFileEntry (proxyFile, &entry)) + { + entry->next = proxyFileHead; + proxyFileHead = entry; + } + else + done = 1; + } + + fclose (proxyFile); +} + + + +#ifndef HAS_MKSTEMP +static char * +unique_filename (path, prefix) +char *path; +char *prefix; +#else +static char * +unique_filename (path, prefix, pFd) +char *path; +char *prefix; +int *pFd; +#endif + +{ +#ifndef HAS_MKSTEMP +#ifndef X_NOT_POSIX + return ((char *) tempnam (path, prefix)); +#else + char tempFile[PATH_MAX]; + char *tmp; + + sprintf (tempFile, "%s/%sXXXXXX", path, prefix); + tmp = (char *) mktemp (tempFile); + if (tmp) + { + char *ptr = (char *) malloc (strlen (tmp) + 1); + strcpy (ptr, tmp); + return (ptr); + } + else + return (NULL); +#endif +#else + char tempFile[PATH_MAX]; + char *ptr; + + sprintf (tempFile, "%s/%sXXXXXX", path, prefix); + ptr = (char *)malloc(strlen(tempFile) + 1); + if (ptr != NULL) + { + strcpy(ptr, tempFile); + *pFd = mkstemp(ptr); + } + return ptr; +#endif +} + + + +char * +WriteProxyFile () + +{ + FILE *proxyFile = NULL; + char *filename = NULL; +#ifdef HAS_MKSTEMP + int fd; +#endif + char *path; + WinInfo *winptr; + Bool success = False; + + path = getenv ("SM_SAVE_DIR"); + if (!path) + { + path = getenv ("HOME"); + if (!path) + path = "."; + } + +#ifndef HAS_MKSTEMP + if ((filename = unique_filename (path, ".prx")) == NULL) + goto bad; + + if (!(proxyFile = fopen (filename, "wb"))) + goto bad; +#else + if ((filename = unique_filename (path, ".prx", &fd)) == NULL) + goto bad; + + if (!(proxyFile = fdopen(fd, "wb"))) + goto bad; +#endif + if (!write_short (proxyFile, SAVEFILE_VERSION)) + goto bad; + + success = True; + winptr = win_head; + + while (winptr && success) + { + if (winptr->client_id) + if (!WriteProxyFileEntry (proxyFile, winptr)) + { + success = False; + break; + } + + winptr = winptr->next; + } + + bad: + + if (proxyFile) + fclose (proxyFile); + + if (success) + return (filename); + else + { + if (filename) + free (filename); + return (NULL); + } +} + + + +char * +LookupClientID (theWindow) + +WinInfo *theWindow; + +{ + ProxyFileEntry *ptr; + int found = 0; + + ptr = proxyFileHead; + while (ptr && !found) + { + if (!ptr->tag && + strcmp (theWindow->class.res_name, ptr->class.res_name) == 0 && + strcmp (theWindow->class.res_class, ptr->class.res_class) == 0 && + strcmp (theWindow->wm_name, ptr->wm_name) == 0) + { + int i; + + if (theWindow->wm_command_count == ptr->wm_command_count) + { + for (i = 0; i < theWindow->wm_command_count; i++) + if (strcmp (theWindow->wm_command[i], + ptr->wm_command[i]) != 0) + break; + + if (i == theWindow->wm_command_count) + found = 1; + } + } + + if (!found) + ptr = ptr->next; + } + + if (found) + { + ptr->tag = 1; + return (ptr->client_id); + } + else + return NULL; +} |