123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /******************************************************************************
- 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
- ******************************************************************************/
- #include "smproxy.h"
- #ifdef HAVE_MKSTEMP
- #include <unistd.h>
- #endif
- static ProxyFileEntry *proxyFileHead = NULL;
- 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 HAVE_ASPRINTF
- # include <stdarg.h>
- /* sprintf variant found in newer libc's which allocates string to print to */
- _X_HIDDEN int _X_ATTRIBUTE_PRINTF(2,3)
- asprintf(char ** ret, const char *format, ...)
- {
- char buf[256];
- int len;
- va_list ap;
- va_start(ap, format);
- len = vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
- if (len < 0)
- return -1;
- if (len < sizeof(buf))
- {
- *ret = strdup(buf);
- }
- else
- {
- *ret = malloc(len + 1); /* snprintf doesn't count trailing '\0' */
- if (*ret != NULL)
- {
- va_start(ap, format);
- len = vsnprintf(*ret, len + 1, format, ap);
- va_end(ap);
- if (len < 0) {
- free(*ret);
- *ret = NULL;
- }
- }
- }
- if (*ret == NULL)
- return -1;
- return len;
- }
- #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 *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 *file, unsigned char *bp)
- {
- if (fread ((char *) bp, 1, 1, file) != 1)
- return 0;
- return 1;
- }
- static int
- read_short(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 *file, char **stringp)
- {
- unsigned char len;
- char *data;
- if (read_byte (file, &len) == 0)
- return 0;
- if (len == 0) {
- data = NULL;
- } 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(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(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)
- {
- if (entry->wm_command_count)
- {
- for (i = 0; i < entry->wm_command_count; i++)
- if (entry->wm_command[i])
- free (entry->wm_command[i]);
- }
- free ((char *) entry->wm_command);
- }
- free ((char *) entry);
- *pentry = NULL;
- return 0;
- }
- void
- ReadProxyFile(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);
- }
- static char *
- unique_filename(const char *path, const char *prefix, int *pFd)
- {
- char *tempFile = NULL;
- int tempFd = 0;
- #if defined(HAVE_MKSTEMP) || defined(HAVE_MKTEMP)
- if (asprintf (&tempFile, "%s/%sXXXXXX", path, prefix) == -1)
- return NULL;
- #endif
- #ifdef HAVE_MKSTEMP
- tempFd = mkstemp(tempFile);
- #else
- # ifdef HAVE_MKTEMP
- if (mktemp(tempFile) == NULL)
- tempFd = -1;
- # else /* fallback to tempnam */
- tempFile = tempnam (path, prefix);
- # endif /* HAVE_MKTEMP */
- if (tempFd != -1 && tempFile != NULL)
- tempFd = open(tempFile, O_RDWR | O_CREAT | O_EXCL, 0600);
- #endif
- if (tempFd == -1) {
- free(tempFile);
- return (NULL);
- }
- *pFd = tempFd;
- return tempFile;
- }
- char *
- WriteProxyFile(void)
- {
- FILE *proxyFile = NULL;
- char *filename = NULL;
- int fd = -1;
- const char *path;
- WinInfo *winptr;
- Bool success = False;
- path = getenv ("SM_SAVE_DIR");
- if (!path)
- {
- path = getenv ("HOME");
- if (!path)
- path = ".";
- }
- if ((filename = unique_filename (path, ".prx", &fd)) == NULL)
- goto bad;
- if (!(proxyFile = fdopen(fd, "wb")))
- goto bad;
- 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);
- else if (fd != -1)
- close (fd);
- if (success)
- return (filename);
- else
- {
- if (filename)
- free (filename);
- return (NULL);
- }
- }
- char *
- LookupClientID(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;
- }
|