save.c revision 14c0a534
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 3614c0a534SmrgProxyFileEntry *proxyFileHead = NULL; 3714c0a534Smrg 3814c0a534Smrgextern WinInfo *win_head; 3914c0a534Smrg 4014c0a534Smrgstatic int write_byte ( FILE *file, unsigned char b ); 4114c0a534Smrgstatic int write_short ( FILE *file, unsigned short s ); 4214c0a534Smrgstatic int write_counted_string ( FILE *file, char *string ); 4314c0a534Smrgstatic int read_byte ( FILE *file, unsigned char *bp ); 4414c0a534Smrgstatic int read_short ( FILE *file, unsigned short *shortp ); 4514c0a534Smrgstatic int read_counted_string ( FILE *file, char **stringp ); 4614c0a534Smrg#ifndef HAS_MKSTEMP 4714c0a534Smrgstatic char * unique_filename ( char *path, char *prefix ); 4814c0a534Smrg#else 4914c0a534Smrgstatic char * unique_filename ( char *path, char *prefix, int *pFd ); 5014c0a534Smrg#endif 5114c0a534Smrg 5214c0a534Smrg 5314c0a534Smrgstatic int 5414c0a534Smrgwrite_byte (FILE *file, unsigned char b) 5514c0a534Smrg{ 5614c0a534Smrg if (fwrite ((char *) &b, 1, 1, file) != 1) 5714c0a534Smrg return 0; 5814c0a534Smrg return 1; 5914c0a534Smrg} 6014c0a534Smrg 6114c0a534Smrg 6214c0a534Smrgstatic int 6314c0a534Smrgwrite_short (FILE *file, unsigned short s) 6414c0a534Smrg{ 6514c0a534Smrg unsigned char file_short[2]; 6614c0a534Smrg 6714c0a534Smrg file_short[0] = (s & (unsigned)0xff00) >> 8; 6814c0a534Smrg file_short[1] = s & 0xff; 6914c0a534Smrg if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 7014c0a534Smrg return 0; 7114c0a534Smrg return 1; 7214c0a534Smrg} 7314c0a534Smrg 7414c0a534Smrg 7514c0a534Smrgstatic int 7614c0a534Smrgwrite_counted_string (file, string) 7714c0a534Smrg 7814c0a534SmrgFILE *file; 7914c0a534Smrgchar *string; 8014c0a534Smrg 8114c0a534Smrg{ 8214c0a534Smrg if (string) 8314c0a534Smrg { 8414c0a534Smrg unsigned char count = strlen (string); 8514c0a534Smrg 8614c0a534Smrg if (write_byte (file, count) == 0) 8714c0a534Smrg return 0; 8814c0a534Smrg if (fwrite (string, (int) sizeof (char), (int) count, file) != count) 8914c0a534Smrg return 0; 9014c0a534Smrg } 9114c0a534Smrg else 9214c0a534Smrg { 9314c0a534Smrg if (write_byte (file, 0) == 0) 9414c0a534Smrg return 0; 9514c0a534Smrg } 9614c0a534Smrg 9714c0a534Smrg return 1; 9814c0a534Smrg} 9914c0a534Smrg 10014c0a534Smrg 10114c0a534Smrg 10214c0a534Smrgstatic int 10314c0a534Smrgread_byte (file, bp) 10414c0a534Smrg 10514c0a534SmrgFILE *file; 10614c0a534Smrgunsigned char *bp; 10714c0a534Smrg 10814c0a534Smrg{ 10914c0a534Smrg if (fread ((char *) bp, 1, 1, file) != 1) 11014c0a534Smrg return 0; 11114c0a534Smrg return 1; 11214c0a534Smrg} 11314c0a534Smrg 11414c0a534Smrg 11514c0a534Smrgstatic int 11614c0a534Smrgread_short (file, shortp) 11714c0a534Smrg 11814c0a534SmrgFILE *file; 11914c0a534Smrgunsigned short *shortp; 12014c0a534Smrg 12114c0a534Smrg{ 12214c0a534Smrg unsigned char file_short[2]; 12314c0a534Smrg 12414c0a534Smrg if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) 12514c0a534Smrg return 0; 12614c0a534Smrg *shortp = file_short[0] * 256 + file_short[1]; 12714c0a534Smrg return 1; 12814c0a534Smrg} 12914c0a534Smrg 13014c0a534Smrg 13114c0a534Smrgstatic int 13214c0a534Smrgread_counted_string (file, stringp) 13314c0a534Smrg 13414c0a534SmrgFILE *file; 13514c0a534Smrgchar **stringp; 13614c0a534Smrg 13714c0a534Smrg{ 13814c0a534Smrg unsigned char len; 13914c0a534Smrg char *data; 14014c0a534Smrg 14114c0a534Smrg if (read_byte (file, &len) == 0) 14214c0a534Smrg return 0; 14314c0a534Smrg if (len == 0) { 14414c0a534Smrg data = 0; 14514c0a534Smrg } else { 14614c0a534Smrg data = (char *) malloc ((unsigned) len + 1); 14714c0a534Smrg if (!data) 14814c0a534Smrg return 0; 14914c0a534Smrg if (fread (data, (int) sizeof (char), (int) len, file) != len) { 15014c0a534Smrg free (data); 15114c0a534Smrg return 0; 15214c0a534Smrg } 15314c0a534Smrg data[len] = '\0'; 15414c0a534Smrg } 15514c0a534Smrg *stringp = data; 15614c0a534Smrg return 1; 15714c0a534Smrg} 15814c0a534Smrg 15914c0a534Smrg 16014c0a534Smrg 16114c0a534Smrg/* 16214c0a534Smrg * An entry in the .smproxy file looks like this: 16314c0a534Smrg * 16414c0a534Smrg * FIELD BYTES 16514c0a534Smrg * ----- ---- 16614c0a534Smrg * client ID len 1 16714c0a534Smrg * client ID LIST of bytes 16814c0a534Smrg * WM_CLASS "res name" length 1 16914c0a534Smrg * WM_CLASS "res name" LIST of bytes 17014c0a534Smrg * WM_CLASS "res class" length 1 17114c0a534Smrg * WM_CLASS "res class" LIST of bytes 17214c0a534Smrg * WM_NAME length 1 17314c0a534Smrg * WM_NAME LIST of bytes 17414c0a534Smrg * WM_COMMAND arg count 1 17514c0a534Smrg * For each arg in WM_COMMAND 17614c0a534Smrg * arg length 1 17714c0a534Smrg * arg LIST of bytes 17814c0a534Smrg */ 17914c0a534Smrg 18014c0a534Smrgint 18114c0a534SmrgWriteProxyFileEntry (proxyFile, theWindow) 18214c0a534Smrg 18314c0a534SmrgFILE *proxyFile; 18414c0a534SmrgWinInfo *theWindow; 18514c0a534Smrg 18614c0a534Smrg{ 18714c0a534Smrg int i; 18814c0a534Smrg 18914c0a534Smrg if (!write_counted_string (proxyFile, theWindow->client_id)) 19014c0a534Smrg return 0; 19114c0a534Smrg if (!write_counted_string (proxyFile, theWindow->class.res_name)) 19214c0a534Smrg return 0; 19314c0a534Smrg if (!write_counted_string (proxyFile, theWindow->class.res_class)) 19414c0a534Smrg return 0; 19514c0a534Smrg if (!write_counted_string (proxyFile, theWindow->wm_name)) 19614c0a534Smrg return 0; 19714c0a534Smrg 19814c0a534Smrg if (!theWindow->wm_command || theWindow->wm_command_count == 0) 19914c0a534Smrg { 20014c0a534Smrg if (!write_byte (proxyFile, 0)) 20114c0a534Smrg return 0; 20214c0a534Smrg } 20314c0a534Smrg else 20414c0a534Smrg { 20514c0a534Smrg if (!write_byte (proxyFile, (char) theWindow->wm_command_count)) 20614c0a534Smrg return 0; 20714c0a534Smrg for (i = 0; i < theWindow->wm_command_count; i++) 20814c0a534Smrg if (!write_counted_string (proxyFile, theWindow->wm_command[i])) 20914c0a534Smrg return 0; 21014c0a534Smrg } 21114c0a534Smrg 21214c0a534Smrg return 1; 21314c0a534Smrg} 21414c0a534Smrg 21514c0a534Smrg 21614c0a534Smrgint 21714c0a534SmrgReadProxyFileEntry (proxyFile, pentry) 21814c0a534Smrg 21914c0a534SmrgFILE *proxyFile; 22014c0a534SmrgProxyFileEntry **pentry; 22114c0a534Smrg 22214c0a534Smrg{ 22314c0a534Smrg ProxyFileEntry *entry; 22414c0a534Smrg unsigned char byte; 22514c0a534Smrg int i; 22614c0a534Smrg 22714c0a534Smrg *pentry = entry = (ProxyFileEntry *) malloc ( 22814c0a534Smrg sizeof (ProxyFileEntry)); 22914c0a534Smrg if (!*pentry) 23014c0a534Smrg return 0; 23114c0a534Smrg 23214c0a534Smrg entry->tag = 0; 23314c0a534Smrg entry->client_id = NULL; 23414c0a534Smrg entry->class.res_name = NULL; 23514c0a534Smrg entry->class.res_class = NULL; 23614c0a534Smrg entry->wm_name = NULL; 23714c0a534Smrg entry->wm_command = NULL; 23814c0a534Smrg entry->wm_command_count = 0; 23914c0a534Smrg 24014c0a534Smrg if (!read_counted_string (proxyFile, &entry->client_id)) 24114c0a534Smrg goto give_up; 24214c0a534Smrg if (!read_counted_string (proxyFile, &entry->class.res_name)) 24314c0a534Smrg goto give_up; 24414c0a534Smrg if (!read_counted_string (proxyFile, &entry->class.res_class)) 24514c0a534Smrg goto give_up; 24614c0a534Smrg if (!read_counted_string (proxyFile, &entry->wm_name)) 24714c0a534Smrg goto give_up; 24814c0a534Smrg 24914c0a534Smrg if (!read_byte (proxyFile, &byte)) 25014c0a534Smrg goto give_up; 25114c0a534Smrg entry->wm_command_count = byte; 25214c0a534Smrg 25314c0a534Smrg if (entry->wm_command_count == 0) 25414c0a534Smrg entry->wm_command = NULL; 25514c0a534Smrg else 25614c0a534Smrg { 25714c0a534Smrg entry->wm_command = (char **) malloc (entry->wm_command_count * 25814c0a534Smrg sizeof (char *)); 25914c0a534Smrg 26014c0a534Smrg if (!entry->wm_command) 26114c0a534Smrg goto give_up; 26214c0a534Smrg 26314c0a534Smrg for (i = 0; i < entry->wm_command_count; i++) 26414c0a534Smrg if (!read_counted_string (proxyFile, &entry->wm_command[i])) 26514c0a534Smrg goto give_up; 26614c0a534Smrg } 26714c0a534Smrg 26814c0a534Smrg return 1; 26914c0a534Smrg 27014c0a534Smrggive_up: 27114c0a534Smrg 27214c0a534Smrg if (entry->client_id) 27314c0a534Smrg free (entry->client_id); 27414c0a534Smrg if (entry->class.res_name) 27514c0a534Smrg free (entry->class.res_name); 27614c0a534Smrg if (entry->class.res_class) 27714c0a534Smrg free (entry->class.res_class); 27814c0a534Smrg if (entry->wm_name) 27914c0a534Smrg free (entry->wm_name); 28014c0a534Smrg if (entry->wm_command_count) 28114c0a534Smrg { 28214c0a534Smrg for (i = 0; i < entry->wm_command_count; i++) 28314c0a534Smrg if (entry->wm_command[i]) 28414c0a534Smrg free (entry->wm_command[i]); 28514c0a534Smrg } 28614c0a534Smrg if (entry->wm_command) 28714c0a534Smrg free ((char *) entry->wm_command); 28814c0a534Smrg 28914c0a534Smrg free ((char *) entry); 29014c0a534Smrg *pentry = NULL; 29114c0a534Smrg 29214c0a534Smrg return 0; 29314c0a534Smrg} 29414c0a534Smrg 29514c0a534Smrg 29614c0a534Smrgvoid 29714c0a534SmrgReadProxyFile (filename) 29814c0a534Smrg 29914c0a534Smrgchar *filename; 30014c0a534Smrg 30114c0a534Smrg{ 30214c0a534Smrg FILE *proxyFile; 30314c0a534Smrg ProxyFileEntry *entry; 30414c0a534Smrg int done = 0; 30514c0a534Smrg unsigned short version; 30614c0a534Smrg 30714c0a534Smrg proxyFile = fopen (filename, "rb"); 30814c0a534Smrg if (!proxyFile) 30914c0a534Smrg return; 31014c0a534Smrg 31114c0a534Smrg if (!read_short (proxyFile, &version) || 31214c0a534Smrg version > SAVEFILE_VERSION) 31314c0a534Smrg { 31414c0a534Smrg done = 1; 31514c0a534Smrg } 31614c0a534Smrg 31714c0a534Smrg while (!done) 31814c0a534Smrg { 31914c0a534Smrg if (ReadProxyFileEntry (proxyFile, &entry)) 32014c0a534Smrg { 32114c0a534Smrg entry->next = proxyFileHead; 32214c0a534Smrg proxyFileHead = entry; 32314c0a534Smrg } 32414c0a534Smrg else 32514c0a534Smrg done = 1; 32614c0a534Smrg } 32714c0a534Smrg 32814c0a534Smrg fclose (proxyFile); 32914c0a534Smrg} 33014c0a534Smrg 33114c0a534Smrg 33214c0a534Smrg 33314c0a534Smrg#ifndef HAS_MKSTEMP 33414c0a534Smrgstatic char * 33514c0a534Smrgunique_filename (path, prefix) 33614c0a534Smrgchar *path; 33714c0a534Smrgchar *prefix; 33814c0a534Smrg#else 33914c0a534Smrgstatic char * 34014c0a534Smrgunique_filename (path, prefix, pFd) 34114c0a534Smrgchar *path; 34214c0a534Smrgchar *prefix; 34314c0a534Smrgint *pFd; 34414c0a534Smrg#endif 34514c0a534Smrg 34614c0a534Smrg{ 34714c0a534Smrg#ifndef HAS_MKSTEMP 34814c0a534Smrg#ifndef X_NOT_POSIX 34914c0a534Smrg return ((char *) tempnam (path, prefix)); 35014c0a534Smrg#else 35114c0a534Smrg char tempFile[PATH_MAX]; 35214c0a534Smrg char *tmp; 35314c0a534Smrg 35414c0a534Smrg sprintf (tempFile, "%s/%sXXXXXX", path, prefix); 35514c0a534Smrg tmp = (char *) mktemp (tempFile); 35614c0a534Smrg if (tmp) 35714c0a534Smrg { 35814c0a534Smrg char *ptr = (char *) malloc (strlen (tmp) + 1); 35914c0a534Smrg strcpy (ptr, tmp); 36014c0a534Smrg return (ptr); 36114c0a534Smrg } 36214c0a534Smrg else 36314c0a534Smrg return (NULL); 36414c0a534Smrg#endif 36514c0a534Smrg#else 36614c0a534Smrg char tempFile[PATH_MAX]; 36714c0a534Smrg char *ptr; 36814c0a534Smrg 36914c0a534Smrg sprintf (tempFile, "%s/%sXXXXXX", path, prefix); 37014c0a534Smrg ptr = (char *)malloc(strlen(tempFile) + 1); 37114c0a534Smrg if (ptr != NULL) 37214c0a534Smrg { 37314c0a534Smrg strcpy(ptr, tempFile); 37414c0a534Smrg *pFd = mkstemp(ptr); 37514c0a534Smrg } 37614c0a534Smrg return ptr; 37714c0a534Smrg#endif 37814c0a534Smrg} 37914c0a534Smrg 38014c0a534Smrg 38114c0a534Smrg 38214c0a534Smrgchar * 38314c0a534SmrgWriteProxyFile () 38414c0a534Smrg 38514c0a534Smrg{ 38614c0a534Smrg FILE *proxyFile = NULL; 38714c0a534Smrg char *filename = NULL; 38814c0a534Smrg#ifdef HAS_MKSTEMP 38914c0a534Smrg int fd; 39014c0a534Smrg#endif 39114c0a534Smrg char *path; 39214c0a534Smrg WinInfo *winptr; 39314c0a534Smrg Bool success = False; 39414c0a534Smrg 39514c0a534Smrg path = getenv ("SM_SAVE_DIR"); 39614c0a534Smrg if (!path) 39714c0a534Smrg { 39814c0a534Smrg path = getenv ("HOME"); 39914c0a534Smrg if (!path) 40014c0a534Smrg path = "."; 40114c0a534Smrg } 40214c0a534Smrg 40314c0a534Smrg#ifndef HAS_MKSTEMP 40414c0a534Smrg if ((filename = unique_filename (path, ".prx")) == NULL) 40514c0a534Smrg goto bad; 40614c0a534Smrg 40714c0a534Smrg if (!(proxyFile = fopen (filename, "wb"))) 40814c0a534Smrg goto bad; 40914c0a534Smrg#else 41014c0a534Smrg if ((filename = unique_filename (path, ".prx", &fd)) == NULL) 41114c0a534Smrg goto bad; 41214c0a534Smrg 41314c0a534Smrg if (!(proxyFile = fdopen(fd, "wb"))) 41414c0a534Smrg goto bad; 41514c0a534Smrg#endif 41614c0a534Smrg if (!write_short (proxyFile, SAVEFILE_VERSION)) 41714c0a534Smrg goto bad; 41814c0a534Smrg 41914c0a534Smrg success = True; 42014c0a534Smrg winptr = win_head; 42114c0a534Smrg 42214c0a534Smrg while (winptr && success) 42314c0a534Smrg { 42414c0a534Smrg if (winptr->client_id) 42514c0a534Smrg if (!WriteProxyFileEntry (proxyFile, winptr)) 42614c0a534Smrg { 42714c0a534Smrg success = False; 42814c0a534Smrg break; 42914c0a534Smrg } 43014c0a534Smrg 43114c0a534Smrg winptr = winptr->next; 43214c0a534Smrg } 43314c0a534Smrg 43414c0a534Smrg bad: 43514c0a534Smrg 43614c0a534Smrg if (proxyFile) 43714c0a534Smrg fclose (proxyFile); 43814c0a534Smrg 43914c0a534Smrg if (success) 44014c0a534Smrg return (filename); 44114c0a534Smrg else 44214c0a534Smrg { 44314c0a534Smrg if (filename) 44414c0a534Smrg free (filename); 44514c0a534Smrg return (NULL); 44614c0a534Smrg } 44714c0a534Smrg} 44814c0a534Smrg 44914c0a534Smrg 45014c0a534Smrg 45114c0a534Smrgchar * 45214c0a534SmrgLookupClientID (theWindow) 45314c0a534Smrg 45414c0a534SmrgWinInfo *theWindow; 45514c0a534Smrg 45614c0a534Smrg{ 45714c0a534Smrg ProxyFileEntry *ptr; 45814c0a534Smrg int found = 0; 45914c0a534Smrg 46014c0a534Smrg ptr = proxyFileHead; 46114c0a534Smrg while (ptr && !found) 46214c0a534Smrg { 46314c0a534Smrg if (!ptr->tag && 46414c0a534Smrg strcmp (theWindow->class.res_name, ptr->class.res_name) == 0 && 46514c0a534Smrg strcmp (theWindow->class.res_class, ptr->class.res_class) == 0 && 46614c0a534Smrg strcmp (theWindow->wm_name, ptr->wm_name) == 0) 46714c0a534Smrg { 46814c0a534Smrg int i; 46914c0a534Smrg 47014c0a534Smrg if (theWindow->wm_command_count == ptr->wm_command_count) 47114c0a534Smrg { 47214c0a534Smrg for (i = 0; i < theWindow->wm_command_count; i++) 47314c0a534Smrg if (strcmp (theWindow->wm_command[i], 47414c0a534Smrg ptr->wm_command[i]) != 0) 47514c0a534Smrg break; 47614c0a534Smrg 47714c0a534Smrg if (i == theWindow->wm_command_count) 47814c0a534Smrg found = 1; 47914c0a534Smrg } 48014c0a534Smrg } 48114c0a534Smrg 48214c0a534Smrg if (!found) 48314c0a534Smrg ptr = ptr->next; 48414c0a534Smrg } 48514c0a534Smrg 48614c0a534Smrg if (found) 48714c0a534Smrg { 48814c0a534Smrg ptr->tag = 1; 48914c0a534Smrg return (ptr->client_id); 49014c0a534Smrg } 49114c0a534Smrg else 49214c0a534Smrg return NULL; 49314c0a534Smrg} 494