save.c revision bf2eeab3
114c0a534Smrg/* $Xorg: save.c,v 1.4 2001/02/09 02:05:35 xorgcvs Exp $ */ 214c0a534Smrg/****************************************************************************** 314c0a534Smrg 414c0a534SmrgCopyright 1994, 1998 The Open Group 514c0a534Smrg 614c0a534SmrgPermission to use, copy, modify, distribute, and sell this software and its 714c0a534Smrgdocumentation for any purpose is hereby granted without fee, provided that 814c0a534Smrgthe above copyright notice appear in all copies and that both that 914c0a534Smrgcopyright notice and this permission notice appear in supporting 1014c0a534Smrgdocumentation. 1114c0a534Smrg 1214c0a534SmrgThe above copyright notice and this permission notice shall be included in 1314c0a534Smrgall copies or substantial portions of the Software. 1414c0a534Smrg 1514c0a534SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1614c0a534SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1714c0a534SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1814c0a534SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1914c0a534SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2014c0a534SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2114c0a534Smrg 2214c0a534SmrgExcept as contained in this notice, the name of The Open Group shall not be 2314c0a534Smrgused in advertising or otherwise to promote the sale, use or other dealings 2414c0a534Smrgin this Software without prior written authorization from The Open Group. 2514c0a534Smrg 2614c0a534SmrgAuthor: Ralph Mor, X Consortium 2714c0a534Smrg******************************************************************************/ 2814c0a534Smrg/* $XFree86: xc/programs/smproxy/save.c,v 1.7 2001/01/17 23:45:04 dawes Exp $ */ 2914c0a534Smrg 3014c0a534Smrg#include "smproxy.h" 3114c0a534Smrg#ifdef HAS_MKSTEMP 3214c0a534Smrg#include <unistd.h> 3314c0a534Smrg#endif 3414c0a534Smrg 3514c0a534Smrg 36bf2eeab3Smrgstatic ProxyFileEntry *proxyFileHead = NULL; 3714c0a534Smrg 3814c0a534Smrgstatic int write_byte ( FILE *file, unsigned char b ); 3914c0a534Smrgstatic int write_short ( FILE *file, unsigned short s ); 4014c0a534Smrgstatic int write_counted_string ( FILE *file, char *string ); 4114c0a534Smrgstatic int read_byte ( FILE *file, unsigned char *bp ); 4214c0a534Smrgstatic int read_short ( FILE *file, unsigned short *shortp ); 4314c0a534Smrgstatic int read_counted_string ( FILE *file, char **stringp ); 4414c0a534Smrg#ifndef HAS_MKSTEMP 4514c0a534Smrgstatic char * unique_filename ( char *path, char *prefix ); 4614c0a534Smrg#else 4714c0a534Smrgstatic char * unique_filename ( char *path, char *prefix, int *pFd ); 4814c0a534Smrg#endif 4914c0a534Smrg 5014c0a534Smrg 5114c0a534Smrgstatic int 5214c0a534Smrgwrite_byte (FILE *file, unsigned char b) 5314c0a534Smrg{ 5414c0a534Smrg if (fwrite ((char *) &b, 1, 1, file) != 1) 5514c0a534Smrg return 0; 5614c0a534Smrg return 1; 5714c0a534Smrg} 5814c0a534Smrg 5914c0a534Smrg 6014c0a534Smrgstatic int 6114c0a534Smrgwrite_short (FILE *file, unsigned short s) 6214c0a534Smrg{ 6314c0a534Smrg unsigned char file_short[2]; 6414c0a534Smrg 6514c0a534Smrg file_short[0] = (s & (unsigned)0xff00) >> 8; 6614c0a534Smrg file_short[1] = s & 0xff; 6714c0a534Smrg if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 6814c0a534Smrg return 0; 6914c0a534Smrg return 1; 7014c0a534Smrg} 7114c0a534Smrg 7214c0a534Smrg 7314c0a534Smrgstatic int 74bf2eeab3Smrgwrite_counted_string(FILE *file, char *string) 7514c0a534Smrg{ 7614c0a534Smrg if (string) 7714c0a534Smrg { 7814c0a534Smrg unsigned char count = strlen (string); 7914c0a534Smrg 8014c0a534Smrg if (write_byte (file, count) == 0) 8114c0a534Smrg return 0; 8214c0a534Smrg if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 8314c0a534Smrg return 0; 8414c0a534Smrg } 8514c0a534Smrg else 8614c0a534Smrg { 8714c0a534Smrg if (write_byte (file, 0) == 0) 8814c0a534Smrg return 0; 8914c0a534Smrg } 9014c0a534Smrg 9114c0a534Smrg return 1; 9214c0a534Smrg} 9314c0a534Smrg 9414c0a534Smrg 9514c0a534Smrg 9614c0a534Smrgstatic int 97bf2eeab3Smrgread_byte(FILE *file, unsigned char *bp) 9814c0a534Smrg{ 9914c0a534Smrg if (fread ((char *) bp, 1, 1, file) != 1) 10014c0a534Smrg return 0; 10114c0a534Smrg return 1; 10214c0a534Smrg} 10314c0a534Smrg 10414c0a534Smrg 10514c0a534Smrgstatic int 106bf2eeab3Smrgread_short(FILE *file, unsigned short *shortp) 10714c0a534Smrg{ 10814c0a534Smrg unsigned char file_short[2]; 10914c0a534Smrg 11014c0a534Smrg if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 11114c0a534Smrg return 0; 11214c0a534Smrg *shortp = file_short[0] * 256 + file_short[1]; 11314c0a534Smrg return 1; 11414c0a534Smrg} 11514c0a534Smrg 11614c0a534Smrg 11714c0a534Smrgstatic int 118bf2eeab3Smrgread_counted_string(FILE *file, char **stringp) 11914c0a534Smrg{ 12014c0a534Smrg unsigned char len; 12114c0a534Smrg char *data; 12214c0a534Smrg 12314c0a534Smrg if (read_byte (file, &len) == 0) 12414c0a534Smrg return 0; 12514c0a534Smrg if (len == 0) { 126bf2eeab3Smrg data = NULL; 12714c0a534Smrg } else { 12814c0a534Smrg data = (char *) malloc ((unsigned) len + 1); 12914c0a534Smrg if (!data) 13014c0a534Smrg return 0; 13114c0a534Smrg if (fread (data, (int) sizeof (char), (int) len, file) != len) { 13214c0a534Smrg free (data); 13314c0a534Smrg return 0; 13414c0a534Smrg } 13514c0a534Smrg data[len] = '\0'; 13614c0a534Smrg } 13714c0a534Smrg *stringp = data; 13814c0a534Smrg return 1; 13914c0a534Smrg} 14014c0a534Smrg 14114c0a534Smrg 14214c0a534Smrg 14314c0a534Smrg/* 14414c0a534Smrg * An entry in the .smproxy file looks like this: 14514c0a534Smrg * 14614c0a534Smrg * FIELD BYTES 14714c0a534Smrg * ----- ---- 14814c0a534Smrg * client ID len 1 14914c0a534Smrg * client ID LIST of bytes 15014c0a534Smrg * WM_CLASS "res name" length 1 15114c0a534Smrg * WM_CLASS "res name" LIST of bytes 15214c0a534Smrg * WM_CLASS "res class" length 1 15314c0a534Smrg * WM_CLASS "res class" LIST of bytes 15414c0a534Smrg * WM_NAME length 1 15514c0a534Smrg * WM_NAME LIST of bytes 15614c0a534Smrg * WM_COMMAND arg count 1 15714c0a534Smrg * For each arg in WM_COMMAND 15814c0a534Smrg * arg length 1 15914c0a534Smrg * arg LIST of bytes 16014c0a534Smrg */ 16114c0a534Smrg 16214c0a534Smrgint 163bf2eeab3SmrgWriteProxyFileEntry(FILE *proxyFile, WinInfo *theWindow) 16414c0a534Smrg{ 16514c0a534Smrg int i; 16614c0a534Smrg 16714c0a534Smrg if (!write_counted_string (proxyFile, theWindow->client_id)) 16814c0a534Smrg return 0; 16914c0a534Smrg if (!write_counted_string (proxyFile, theWindow->class.res_name)) 17014c0a534Smrg return 0; 17114c0a534Smrg if (!write_counted_string (proxyFile, theWindow->class.res_class)) 17214c0a534Smrg return 0; 17314c0a534Smrg if (!write_counted_string (proxyFile, theWindow->wm_name)) 17414c0a534Smrg return 0; 17514c0a534Smrg 17614c0a534Smrg if (!theWindow->wm_command || theWindow->wm_command_count == 0) 17714c0a534Smrg { 17814c0a534Smrg if (!write_byte (proxyFile, 0)) 17914c0a534Smrg return 0; 18014c0a534Smrg } 18114c0a534Smrg else 18214c0a534Smrg { 18314c0a534Smrg if (!write_byte (proxyFile, (char) theWindow->wm_command_count)) 18414c0a534Smrg return 0; 18514c0a534Smrg for (i = 0; i < theWindow->wm_command_count; i++) 18614c0a534Smrg if (!write_counted_string (proxyFile, theWindow->wm_command[i])) 18714c0a534Smrg return 0; 18814c0a534Smrg } 18914c0a534Smrg 19014c0a534Smrg return 1; 19114c0a534Smrg} 19214c0a534Smrg 19314c0a534Smrg 19414c0a534Smrgint 195bf2eeab3SmrgReadProxyFileEntry(FILE *proxyFile, ProxyFileEntry **pentry) 19614c0a534Smrg{ 19714c0a534Smrg ProxyFileEntry *entry; 19814c0a534Smrg unsigned char byte; 19914c0a534Smrg int i; 20014c0a534Smrg 20114c0a534Smrg *pentry = entry = (ProxyFileEntry *) malloc ( 20214c0a534Smrg sizeof (ProxyFileEntry)); 20314c0a534Smrg if (!*pentry) 20414c0a534Smrg return 0; 20514c0a534Smrg 20614c0a534Smrg entry->tag = 0; 20714c0a534Smrg entry->client_id = NULL; 20814c0a534Smrg entry->class.res_name = NULL; 20914c0a534Smrg entry->class.res_class = NULL; 21014c0a534Smrg entry->wm_name = NULL; 21114c0a534Smrg entry->wm_command = NULL; 21214c0a534Smrg entry->wm_command_count = 0; 21314c0a534Smrg 21414c0a534Smrg if (!read_counted_string (proxyFile, &entry->client_id)) 21514c0a534Smrg goto give_up; 21614c0a534Smrg if (!read_counted_string (proxyFile, &entry->class.res_name)) 21714c0a534Smrg goto give_up; 21814c0a534Smrg if (!read_counted_string (proxyFile, &entry->class.res_class)) 21914c0a534Smrg goto give_up; 22014c0a534Smrg if (!read_counted_string (proxyFile, &entry->wm_name)) 22114c0a534Smrg goto give_up; 22214c0a534Smrg 22314c0a534Smrg if (!read_byte (proxyFile, &byte)) 22414c0a534Smrg goto give_up; 22514c0a534Smrg entry->wm_command_count = byte; 22614c0a534Smrg 22714c0a534Smrg if (entry->wm_command_count == 0) 22814c0a534Smrg entry->wm_command = NULL; 22914c0a534Smrg else 23014c0a534Smrg { 23114c0a534Smrg entry->wm_command = (char **) malloc (entry->wm_command_count * 23214c0a534Smrg sizeof (char *)); 23314c0a534Smrg 23414c0a534Smrg if (!entry->wm_command) 23514c0a534Smrg goto give_up; 23614c0a534Smrg 23714c0a534Smrg for (i = 0; i < entry->wm_command_count; i++) 23814c0a534Smrg if (!read_counted_string (proxyFile, &entry->wm_command[i])) 23914c0a534Smrg goto give_up; 24014c0a534Smrg } 24114c0a534Smrg 24214c0a534Smrg return 1; 24314c0a534Smrg 24414c0a534Smrggive_up: 24514c0a534Smrg 24614c0a534Smrg if (entry->client_id) 24714c0a534Smrg free (entry->client_id); 24814c0a534Smrg if (entry->class.res_name) 24914c0a534Smrg free (entry->class.res_name); 25014c0a534Smrg if (entry->class.res_class) 25114c0a534Smrg free (entry->class.res_class); 25214c0a534Smrg if (entry->wm_name) 25314c0a534Smrg free (entry->wm_name); 25414c0a534Smrg if (entry->wm_command_count) 25514c0a534Smrg { 25614c0a534Smrg for (i = 0; i < entry->wm_command_count; i++) 25714c0a534Smrg if (entry->wm_command[i]) 25814c0a534Smrg free (entry->wm_command[i]); 25914c0a534Smrg } 26014c0a534Smrg if (entry->wm_command) 26114c0a534Smrg free ((char *) entry->wm_command); 26214c0a534Smrg 26314c0a534Smrg free ((char *) entry); 26414c0a534Smrg *pentry = NULL; 26514c0a534Smrg 26614c0a534Smrg return 0; 26714c0a534Smrg} 26814c0a534Smrg 26914c0a534Smrg 27014c0a534Smrgvoid 271bf2eeab3SmrgReadProxyFile(char *filename) 27214c0a534Smrg{ 27314c0a534Smrg FILE *proxyFile; 27414c0a534Smrg ProxyFileEntry *entry; 27514c0a534Smrg int done = 0; 27614c0a534Smrg unsigned short version; 27714c0a534Smrg 27814c0a534Smrg proxyFile = fopen (filename, "rb"); 27914c0a534Smrg if (!proxyFile) 28014c0a534Smrg return; 28114c0a534Smrg 28214c0a534Smrg if (!read_short (proxyFile, &version) || 28314c0a534Smrg version > SAVEFILE_VERSION) 28414c0a534Smrg { 28514c0a534Smrg done = 1; 28614c0a534Smrg } 28714c0a534Smrg 28814c0a534Smrg while (!done) 28914c0a534Smrg { 29014c0a534Smrg if (ReadProxyFileEntry (proxyFile, &entry)) 29114c0a534Smrg { 29214c0a534Smrg entry->next = proxyFileHead; 29314c0a534Smrg proxyFileHead = entry; 29414c0a534Smrg } 29514c0a534Smrg else 29614c0a534Smrg done = 1; 29714c0a534Smrg } 29814c0a534Smrg 29914c0a534Smrg fclose (proxyFile); 30014c0a534Smrg} 30114c0a534Smrg 30214c0a534Smrg 30314c0a534Smrg 30414c0a534Smrg#ifndef HAS_MKSTEMP 30514c0a534Smrgstatic char * 306bf2eeab3Smrgunique_filename(char *path, char *prefix) 30714c0a534Smrg#else 30814c0a534Smrgstatic char * 309bf2eeab3Smrgunique_filename(char *path, char *prefix, int *pFd) 31014c0a534Smrg#endif 31114c0a534Smrg{ 31214c0a534Smrg#ifndef HAS_MKSTEMP 31314c0a534Smrg#ifndef X_NOT_POSIX 31414c0a534Smrg return ((char *) tempnam (path, prefix)); 31514c0a534Smrg#else 31614c0a534Smrg char tempFile[PATH_MAX]; 31714c0a534Smrg char *tmp; 31814c0a534Smrg 31914c0a534Smrg sprintf (tempFile, "%s/%sXXXXXX", path, prefix); 32014c0a534Smrg tmp = (char *) mktemp (tempFile); 32114c0a534Smrg if (tmp) 32214c0a534Smrg { 32314c0a534Smrg char *ptr = (char *) malloc (strlen (tmp) + 1); 32414c0a534Smrg strcpy (ptr, tmp); 32514c0a534Smrg return (ptr); 32614c0a534Smrg } 32714c0a534Smrg else 32814c0a534Smrg return (NULL); 32914c0a534Smrg#endif 33014c0a534Smrg#else 33114c0a534Smrg char tempFile[PATH_MAX]; 33214c0a534Smrg char *ptr; 33314c0a534Smrg 33414c0a534Smrg sprintf (tempFile, "%s/%sXXXXXX", path, prefix); 33514c0a534Smrg ptr = (char *)malloc(strlen(tempFile) + 1); 33614c0a534Smrg if (ptr != NULL) 33714c0a534Smrg { 33814c0a534Smrg strcpy(ptr, tempFile); 33914c0a534Smrg *pFd = mkstemp(ptr); 34014c0a534Smrg } 34114c0a534Smrg return ptr; 34214c0a534Smrg#endif 34314c0a534Smrg} 34414c0a534Smrg 34514c0a534Smrg 34614c0a534Smrg 34714c0a534Smrgchar * 348bf2eeab3SmrgWriteProxyFile(void) 34914c0a534Smrg{ 35014c0a534Smrg FILE *proxyFile = NULL; 35114c0a534Smrg char *filename = NULL; 35214c0a534Smrg#ifdef HAS_MKSTEMP 35314c0a534Smrg int fd; 35414c0a534Smrg#endif 35514c0a534Smrg char *path; 35614c0a534Smrg WinInfo *winptr; 35714c0a534Smrg Bool success = False; 35814c0a534Smrg 35914c0a534Smrg path = getenv ("SM_SAVE_DIR"); 36014c0a534Smrg if (!path) 36114c0a534Smrg { 36214c0a534Smrg path = getenv ("HOME"); 36314c0a534Smrg if (!path) 36414c0a534Smrg path = "."; 36514c0a534Smrg } 36614c0a534Smrg 36714c0a534Smrg#ifndef HAS_MKSTEMP 36814c0a534Smrg if ((filename = unique_filename (path, ".prx")) == NULL) 36914c0a534Smrg goto bad; 37014c0a534Smrg 37114c0a534Smrg if (!(proxyFile = fopen (filename, "wb"))) 37214c0a534Smrg goto bad; 37314c0a534Smrg#else 37414c0a534Smrg if ((filename = unique_filename (path, ".prx", &fd)) == NULL) 37514c0a534Smrg goto bad; 37614c0a534Smrg 37714c0a534Smrg if (!(proxyFile = fdopen(fd, "wb"))) 37814c0a534Smrg goto bad; 37914c0a534Smrg#endif 38014c0a534Smrg if (!write_short (proxyFile, SAVEFILE_VERSION)) 38114c0a534Smrg goto bad; 38214c0a534Smrg 38314c0a534Smrg success = True; 38414c0a534Smrg winptr = win_head; 38514c0a534Smrg 38614c0a534Smrg while (winptr && success) 38714c0a534Smrg { 38814c0a534Smrg if (winptr->client_id) 38914c0a534Smrg if (!WriteProxyFileEntry (proxyFile, winptr)) 39014c0a534Smrg { 39114c0a534Smrg success = False; 39214c0a534Smrg break; 39314c0a534Smrg } 39414c0a534Smrg 39514c0a534Smrg winptr = winptr->next; 39614c0a534Smrg } 39714c0a534Smrg 39814c0a534Smrg bad: 39914c0a534Smrg 40014c0a534Smrg if (proxyFile) 40114c0a534Smrg fclose (proxyFile); 40214c0a534Smrg 40314c0a534Smrg if (success) 40414c0a534Smrg return (filename); 40514c0a534Smrg else 40614c0a534Smrg { 40714c0a534Smrg if (filename) 40814c0a534Smrg free (filename); 40914c0a534Smrg return (NULL); 41014c0a534Smrg } 41114c0a534Smrg} 41214c0a534Smrg 41314c0a534Smrg 41414c0a534Smrg 41514c0a534Smrgchar * 416bf2eeab3SmrgLookupClientID(WinInfo *theWindow) 41714c0a534Smrg{ 41814c0a534Smrg ProxyFileEntry *ptr; 41914c0a534Smrg int found = 0; 42014c0a534Smrg 42114c0a534Smrg ptr = proxyFileHead; 42214c0a534Smrg while (ptr && !found) 42314c0a534Smrg { 42414c0a534Smrg if (!ptr->tag && 42514c0a534Smrg strcmp (theWindow->class.res_name, ptr->class.res_name) == 0 && 42614c0a534Smrg strcmp (theWindow->class.res_class, ptr->class.res_class) == 0 && 42714c0a534Smrg strcmp (theWindow->wm_name, ptr->wm_name) == 0) 42814c0a534Smrg { 42914c0a534Smrg int i; 43014c0a534Smrg 43114c0a534Smrg if (theWindow->wm_command_count == ptr->wm_command_count) 43214c0a534Smrg { 43314c0a534Smrg for (i = 0; i < theWindow->wm_command_count; i++) 43414c0a534Smrg if (strcmp (theWindow->wm_command[i], 43514c0a534Smrg ptr->wm_command[i]) != 0) 43614c0a534Smrg break; 43714c0a534Smrg 43814c0a534Smrg if (i == theWindow->wm_command_count) 43914c0a534Smrg found = 1; 44014c0a534Smrg } 44114c0a534Smrg } 44214c0a534Smrg 44314c0a534Smrg if (!found) 44414c0a534Smrg ptr = ptr->next; 44514c0a534Smrg } 44614c0a534Smrg 44714c0a534Smrg if (found) 44814c0a534Smrg { 44914c0a534Smrg ptr->tag = 1; 45014c0a534Smrg return (ptr->client_id); 45114c0a534Smrg } 45214c0a534Smrg else 45314c0a534Smrg return NULL; 45414c0a534Smrg} 455