Merge branch 'master' of https://git.code.sf.net/p/cdesktopenv/code
[oweals/cde.git] / cde / programs / dtsession / SmMigResources.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: SmMigResources.c /main/4 1996/05/08 20:11:34 drk $ */
24 static char sccsid[] = "@(#)48  1.2  src/cde/cde1/dtsession/SmMigResources.c, desktop, cde41J, 9520A_all 5/16/95 08:31:12";
25 /*
26  *   COMPONENT_NAME: desktop
27  *
28  *   FUNCTIONS: MigrateResources
29  *
30  *   ORIGINS: 27
31  *
32  *   IBM CONFIDENTIAL -- (IBM Confidential Restricted when
33  *   combined with the aggregated modules for this product)
34  *   OBJECT CODE ONLY SOURCE MATERIALS
35  *
36  *   (C) COPYRIGHT International Business Machines Corp. 1995
37  *   All Rights Reserved
38  *   US Government Users Restricted Rights - Use, duplication or
39  *   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
40  */
41 #include <stdio.h>
42 #include <string.h>
43 #include <Dt/DtNlUtils.h>
44
45 /* defines for return codes */
46 #define RC_SUCCESS                         0
47 #define RC_OPEN_ERROR                      1
48 #define RC_END_OF_FILE                     2
49 #define RC_MEMORY_ALLOCATION_ERROR         3
50 #define RC_LINE_CONTINUED                  4
51 #define RC_PARTIAL_LINE                    5
52 #define RC_WRITE_ERROR_TEMP                6
53
54 /* type 1 resources are of the form:
55      [*.]convert1[i]
56
57    Example of a resource specification of this type:
58      *foreground:                        Blue
59 */
60 #define  NUMBER_OF_CONVERT1 15
61 static   char *convert1[NUMBER_OF_CONVERT1]
62 = {
63        "displayResolution",
64        "systemFont",
65        "userFont",
66        "FontList",
67        "Font",
68        "FontSet",
69        "multiClickTime",
70        "sessionVersion",
71        "background",
72        "foreground",
73        "ColorUse",
74        "HelpColorUse",
75        "background",
76        "foreground",
77        "enableBtn1Transfer"
78        }
79        ;
80
81
82 /* type 2 resources are of the form:
83      CONVERT2_0{* or .}CONVERT2_1{* or .}convert2[i]
84
85    Example of a resource specification of this type:
86      dtsession*extension*cycleTimeout:   10
87 */
88 #define CONVERT2_0 "dtsession"
89 #define CONVERT2_1 "extension"
90 #define  NUMBER_OF_CONVERT2 5
91 static   char *convert2[NUMBER_OF_CONVERT2]
92 = {
93        "cycleTimeout",
94        "lockTimeout",
95        "saverTimeout",
96        "random",
97        "saverList",
98        }
99        ;
100
101
102 /* type 3 resources are of the form:
103      convert31[i]{* or .}convert32[i]
104
105    Example of a resource specification of this type:
106      Dtwm*useIconBox:                    True
107 */
108 #define  NUMBER_OF_CONVERT3 26
109 static   char *convert31[NUMBER_OF_CONVERT3]
110 = {
111        "dtsession",
112        "dtsession",
113        "dtsession",
114        "dtsession",
115        "dtsession",
116        "dtsession",
117        "Dtstyle",
118        "Dtstyle",
119        "Dtwm",
120        "Dtwm",
121        "Dtwm",
122        "Dtwm",
123        "wsHelp",
124        "wsHelp",
125        "wsHelp",
126        "wsHelp",
127        "wsHelp",
128        "wsHelp",
129        "wsHelp",
130        "wsHelp",
131        "wsHelp",
132        "wsHelp",
133        "wsHelp",
134        "wsHelp",
135        "wsHelp",
136        "cachedHelp"
137        }
138        ;
139 static   char *convert32[NUMBER_OF_CONVERT3]
140 = {
141        "displayResolution"  ,
142        "sessionLanguage"    ,
143        "saverTimeout"       ,
144        "cycleTimeout"       ,
145        "lockTimeout"        ,
146        "saverList"          ,
147        "lockoutScale"       ,
148        "timeoutScale"       ,
149        "keyboardFocusPolicy",
150        "focusAutoRaise"     ,
151        "moveOpaque"         ,
152        "useIconBox"         ,
153        "onScreen"           ,
154        "x"                  ,
155        "y"                  ,
156        "columns"            ,
157        "rows"               ,
158        "helpType"           ,
159        "vPCount"            ,
160        "tTitle"             ,
161        "helpVolume"         ,
162        "locationId"         ,
163        "stringData"         ,
164        "windowGroup"        ,
165        "wsName"             ,
166        "cachedCount"
167        }
168        ;
169
170 /* type 4 resources are of the form:
171      {* or .}convert4[i]{* or .}CONVERT4_2
172
173    Example of a resource specification of this type:
174        *XmText*FontList:                   Big
175 */
176 #define CONVERT4_2 "FontList"
177 #define  NUMBER_OF_CONVERT4 2
178 static   char *convert4[NUMBER_OF_CONVERT4]
179 = {
180        "XmText",
181        "XmTextField"
182        }
183        ;
184
185
186 /* type 5 resources are of the form:
187      convert5[i]{* or .}<any value>{* or .}CONVERT5_2
188
189    Example of a resource specification of this type:
190        Dtwm*0*helpResources:             xxx
191 */
192 #define CONVERT5_2 "helpResources"
193 #define  NUMBER_OF_CONVERT5 2
194 /* these are of the form p1*#*helpResources */
195 static   char *convert5[NUMBER_OF_CONVERT5]
196 = {
197        "Dtwm",
198        "Mwm"
199        }
200        ;
201
202
203 /* type 6 resources are of the form:
204      CONVERT6_0<any value>{* or .}convert6[i]
205
206    Example of a resource specification of this type:
207        oWsHelp10*x:                       xxx
208 */
209 #define CONVERT6_0 "oWsHelp"
210 #define  NUMBER_OF_CONVERT6 11
211 static   char *convert6[NUMBER_OF_CONVERT6]
212 = {
213       "x",
214       "y",
215       "columns",
216       "rows",
217       "helpType",
218       "vPCount",
219       "tTitle",
220       "helpVolume",
221       "locationId",
222       "stringData",
223       "workspaces"
224        }
225        ;
226
227 /* type 7 resources are of the form:
228      CONVERT7_01{* or .}<any value>{* or .}convert7[i]
229                      - or -
230      CONVERT7_02{* or .}<any value>{* or .}convert7[i]
231
232    Examples of resource specifications of this type:
233      Dtwm*0*initialWorkspace:           xxx
234      Mwm*0*initialWorkspace:            xxx
235 */
236 #define CONVERT7_01 "Mwm"
237 #define CONVERT7_02 "Dtwm"
238 #define  NUMBER_OF_CONVERT7   3
239 /* these are of the form Mwm|Dtwm*XXX*resource */
240 static   char *convert7[NUMBER_OF_CONVERT7]
241 = {
242       "initialWorkspace",
243       "workspaceList",
244       "workspaceCount"
245        }
246        ;
247
248 /* type 8 resources are of the form:
249      CONVERT8_01{* or .}<any value>{* or .}<any value>{* or .}convert8[i]
250                      - or -
251      CONVERT8_02{* or .}<any value>{* or .}<any value>{* or .}convert8[i]
252
253    Examples of resource specifications of this type:
254      Mwm*0*ws01*title:                  xxx
255      Dtwm*1ws02*title:                  xxx
256 */
257 #define CONVERT8_01 "Mwm"
258 #define CONVERT8_02 "Dtwm"
259 #define  NUMBER_OF_CONVERT8  3
260 static   char *convert8[NUMBER_OF_CONVERT8]
261 = {
262       "title",
263       "geometry",
264       "iconBoxGeometry"
265        }
266        ;
267
268 /* type 9 resources are of the form:
269      CONVERT9_01{* or .}<any value>{* or .}<any value>{* or .}convert91[i] \
270              {* or .}convert92[i]
271              - or -
272      CONVERT9_02{* or .}<any value>{* or .}<any value>{* or .}convert91[i]  \
273              {* or .}convert92[i]
274
275    Example of resource specification of this type:
276       Dtwm*0*ws01*backdrop*image:        Drops
277 */
278 #define CONVERT9_01 "Mwm"
279 #define CONVERT9_02 "Dtwm"
280 #define  NUMBER_OF_CONVERT9  3
281 static   char *convert91[NUMBER_OF_CONVERT9]
282 = {
283       "backdrop",
284       "FrontPanel",
285       "MyFrontPanel"
286       }
287        ;
288
289 static   char *convert92[NUMBER_OF_CONVERT9]
290 = {
291       "image" ,
292       "geometry",
293       "geometry"
294       }
295        ;
296
297
298
299 /* type 10 resources are of the form:
300      *<any value>{* or .}convert10[i]
301
302    Example of a resource specification of this type:
303        *0*ColorPalette:        Default.dp
304 */
305 #define  NUMBER_OF_CONVERT10 3
306 static   char *convert10[NUMBER_OF_CONVERT10]
307 = {
308        "MonochromePalette",
309        "ColorUse",
310        "ColorPalette"
311        }
312        ;
313
314
315 /* define the maximum fields in a resource specification
316    (which does not include the value of the resource) that
317    is required by this routine
318 */
319 #define NUMBER_OF_FIELDS 6
320 static   char * field[NUMBER_OF_FIELDS];
321
322 /* this function determines whether a field extracted from the resource
323    matches a string in the specified array.
324    Returns:
325       TRUE   = if strings match
326       FALSE  = if string do not match.
327 */
328 int check_match1(char * match[], int noelements, int match1)
329 {
330    int i;
331    int matched = FALSE;
332    for (i=0;((matched == FALSE) &&
333              (i<noelements));i++)
334    {
335       if (strcmp(field[match1],match[i]) == 0)
336       {
337          matched =TRUE;
338       }
339    }
340    return(matched);
341 }
342 /* this function determines whether a fields extracted from the resource
343    match strings in the specified arrays.
344    Returns:
345       TRUE   = if strings match
346       FALSE  = if string do not match.
347 */
348 int check_match2(char * match1_str[], char * match2_str[],
349                  int noelements, int match1, int match2)
350 {
351    int i;
352    int matched = FALSE;
353    for (i=0;((matched == FALSE) &&
354              (i<noelements));i++)
355    {
356
357       if ((strcmp(field[match1],match1_str[i]) == 0) &&
358           (strcmp(field[match2],match2_str[i]) == 0))
359       {
360          matched =TRUE;
361       }
362    }
363    return(matched);
364 }
365
366 /* this function reads all resources from the input file.
367    If the resource matches those written from within desktop on 4.1.1 and
368    4.1.2, the resource is written to the output file.
369    Otherwise, the resource is not written to the output file.
370
371    Return codes:
372      RC_SUCCESS
373      RC_OPEN_ERROR
374      RC_MEMORY_ALLOCATION_ERROR
375      RC_WRITE_ERROR_TEMP
376
377 */
378 MigrateResources(char * inputfile, char * outputfile)
379 {
380
381    int                           size_of_buffer = 1024;
382    int                           size_of_mbuffer = 1024;
383    int                           rc = RC_SUCCESS;
384    FILE *                        out_fh;
385    FILE *                        in_fh;
386    int                           write_line;
387    int                           chars_written;
388    int                           type_found = FALSE;
389    char *                        string;
390    char *                        realend;
391    int                           done=0;
392    int                           new_size = 0;
393    int                           number_fields = 0;
394    char *                        inputbuffer=NULL;
395    char *                        inputbuffer1=NULL;
396    char *                        unmodified_buffer=NULL;
397    char *                        resource_end;
398    char *                        first_space;
399    char *                        tmp1;
400    int                           i;
401    int                           charlen;
402
403    /* Initialize for multi-byte */
404    DtNlInitialize();
405    done = RC_SUCCESS;
406    /* open input and output files and exit if not successful */
407    in_fh = fopen(inputfile,"r");
408    out_fh = fopen(outputfile,"w");
409    if ((out_fh != NULL) && (in_fh != NULL))
410    {
411
412       /* allocate buffers for reading lines from the input file */
413       inputbuffer = malloc ((size_of_buffer + 1) * sizeof(char *));
414       inputbuffer1 = malloc ((size_of_buffer + 1) * sizeof(char *));
415       unmodified_buffer = malloc ((size_of_mbuffer + 1)
416                                     * sizeof(char *));
417       if ((inputbuffer != NULL) &&
418           (inputbuffer1 != NULL) &&
419           (unmodified_buffer != NULL))
420       {
421           do
422           {
423
424              *inputbuffer = '\0';
425              *inputbuffer1 = '\0';
426              *unmodified_buffer = '\0';
427              /* read and process each line from the input file */
428              do
429
430              {
431                  /* read until an line has been read */
432                  rc = RC_SUCCESS;
433                  string = fgets((char *)inputbuffer1, size_of_buffer, in_fh);
434
435                  /* if read was successful, then ...*/
436                  if (string != NULL)
437                  {
438                       /* determine if a larger unmodified buffer
439                          needs to be allocated
440                       */
441                       new_size = strlen(unmodified_buffer) +
442                                  strlen(inputbuffer1) + 2;
443
444                       if (new_size > size_of_mbuffer)
445                       {
446                           unmodified_buffer = realloc(unmodified_buffer,
447                                                       new_size);
448                           size_of_mbuffer = new_size;
449                       }
450
451                       /* save unmodified data read */
452                       strcat(unmodified_buffer,inputbuffer1);
453
454                       /* set indicator if entire line was not read */
455                       DtLastChar(inputbuffer1,&realend,&charlen);
456                       if ((charlen == 1) && (*realend != '\n'))
457                       {
458                           rc = RC_PARTIAL_LINE;
459                       }
460                       else
461                       {
462                           /* if entire line was read but it ends
463                              with a continuation character
464                              then, remove the ending continuation character or
465                              spaces preceeded by an ending
466                              continuation character.
467                           */
468                           realend=DtPrevChar(inputbuffer1,realend);
469                           for (;((DtIsspace(realend) != 0) &&
470                                  (realend > inputbuffer1));)
471                           {
472                               realend=DtPrevChar(inputbuffer1,realend);
473                           }
474                           if ((mblen(realend,MB_CUR_MAX) == 1) &&
475                               (*realend == '\\'))
476                           {
477                               *realend = '\0';
478                               rc = RC_LINE_CONTINUED;
479                           }
480                       }
481
482                       /* allocate larger input buffer if necessary */
483                       new_size = strlen(inputbuffer) +
484                                  strlen(inputbuffer1) + 2;
485
486                       if (new_size > size_of_buffer)
487                       {
488                           inputbuffer = realloc(inputbuffer,new_size);
489                           size_of_buffer = new_size;
490                       }
491
492                       /* concatenate modified buffer to previously
493                          read buffer
494                       */
495                       strcat(inputbuffer,inputbuffer1);
496                  }
497                  else
498                  {
499                       rc = RC_END_OF_FILE;
500                  }
501              } while ((rc == RC_LINE_CONTINUED) || (rc == RC_PARTIAL_LINE));
502
503              /* if read was successful, then determine if the resources
504                 read are part of the set that need to be retained.
505              */
506              type_found = FALSE;
507              number_fields = 0;
508              type_found=FALSE;
509              if (rc == RC_SUCCESS)
510              {
511                  /* process non-comment lines */
512                  if (strncmp(inputbuffer,"!",1) != 0)
513                  {
514                      /* determine the non-value portion of the
515                         resource specification (i.e. the
516                         part to the left of the ":" and to the
517                         left of the first space).
518                      */
519                      resource_end = DtStrchr(inputbuffer,':');
520                      first_space = DtStrchr(inputbuffer,' ');
521                      if (resource_end != NULL)
522                      {
523                          if ((first_space != NULL) &&
524                              (first_space < resource_end))
525
526                          {
527                              resource_end = NULL;
528                          }
529                      }
530                      if (resource_end != NULL)
531                      {
532                          *resource_end = '\0';
533                          /* determine the start of each field
534                             in the non-value part of the resource.
535                             It is assumed that the individual fields
536                             are delimited by a "*" or ".".
537                          */
538                          field[0]=inputbuffer;
539                          for (i=1;((i<NUMBER_OF_FIELDS) &&
540                                    (field[i-1] != NULL));
541                               i++)
542                          {
543                             /* determine the location of the next
544                                delimiter - "* or "."
545                                Set field pointer to first one found.
546                             */
547                             field[i]=DtStrchr(field[i-1],'*');
548                             tmp1=DtStrchr(field[i-1],'.');
549                             if (((tmp1 != NULL) && (tmp1 < resource_end) &&
550                                  (tmp1 < field[i])) ||
551                                 (field[i] == NULL))
552                             {
553                                 field[i]=tmp1;
554                             }
555                             if (field[i] != NULL)
556                             {
557                                 /* terminate the previous field */
558                                 *field[i] = '\0';
559                                 /* move pointer to start of field */
560                                 field[i]++;
561                             }
562                             if (field[i] >= resource_end)
563                             {
564                                 field[i]=NULL;
565                             }
566                          }
567                          number_fields = i-1;
568                          /* check for each type of resource
569                             that should be retained in the output file.
570                             See comments preceeding the definition
571                             of each array near the start of this file
572                             for a description and example of each type.
573                          */
574                          if ((strlen(field[0]) == 0) &&
575                              (number_fields == 2) &&
576                              (check_match1(convert1,
577                                            NUMBER_OF_CONVERT1,1) == TRUE))
578
579                          {
580                              type_found=TRUE;
581                          }
582                          if ((type_found == FALSE) &&
583                              (number_fields == 3) &&
584                              (strcmp(field[0],CONVERT2_0) == 0) &&
585                              (strcmp(field[1],CONVERT2_1) == 0) &&
586                              (check_match1(convert2, NUMBER_OF_CONVERT2,2)
587                                            == TRUE))
588                          {
589                              type_found=TRUE;
590                          }
591                          if ((type_found == FALSE) &&
592                              (number_fields == 2) &&
593                              (check_match2(convert31,convert32,
594                                  NUMBER_OF_CONVERT3,0,1) == TRUE))
595                          {
596                              type_found=TRUE;
597                          }
598                          if ((type_found == FALSE) &&
599                              (number_fields == 3) &&
600                              (strcmp(field[2],CONVERT4_2) == 0) &&
601                              (check_match1(convert4,
602                                            NUMBER_OF_CONVERT4,1) == TRUE))
603                          {
604                              type_found=TRUE;
605                          }
606                          if ((type_found == FALSE) &&
607                              (number_fields == 3) &&
608                              (strcmp(field[2],CONVERT5_2) == 0) &&
609                              (check_match1(convert5,
610                                            NUMBER_OF_CONVERT5,0) == TRUE))
611                          {
612                              type_found=TRUE;
613                          }
614                          if ((type_found == FALSE) &&
615                              (number_fields == 2) &&
616                              (strlen(field[0]) > strlen(CONVERT6_0)) &&
617                              (strncmp(field[0], CONVERT6_0,
618                                       strlen(CONVERT6_0)) == 0) &&
619                              (check_match1(convert6,
620                                            NUMBER_OF_CONVERT6,1) == TRUE))
621                          {
622                              type_found=TRUE;
623                          }
624                          if ((type_found == FALSE) &&
625                              (number_fields == 3) &&
626                              ((strcmp(field[0],CONVERT7_01) == 0) ||
627                               (strcmp(field[0],CONVERT7_02) == 0)) &&
628                               (check_match1(convert7,
629                                  NUMBER_OF_CONVERT7,2) == TRUE))
630                          {
631
632                              type_found=TRUE;
633                          }
634                          if ((type_found == FALSE) &&
635                              (number_fields == 4) &&
636                              ((strcmp(field[0],CONVERT8_01) == 0) ||
637                               (strcmp(field[0],CONVERT8_02) == 0)) &&
638                              (check_match1(convert8,
639                                            NUMBER_OF_CONVERT8,3) == TRUE))
640                          {
641                              type_found=TRUE;
642                          }
643                          if ((type_found == FALSE) &&
644                              (number_fields == 5) &&
645                              ((strcmp(field[0],CONVERT9_01) == 0) ||
646                               (strcmp(field[0],CONVERT9_02) == 0)) &&
647                              (check_match2(convert91,convert92,
648                                            NUMBER_OF_CONVERT9,3,4) == TRUE))
649                          {
650                              type_found=TRUE;
651                          }
652                          if ((type_found == FALSE) &&
653                              (number_fields == 3) &&
654                              (check_match1(convert10,
655                                            NUMBER_OF_CONVERT10,2) == TRUE))
656                          {
657                              type_found=TRUE;
658                          }
659                      }
660                  }
661
662                  /* if resource should be retained then
663                     write resource to output file.
664                  */
665                  if (type_found == TRUE)
666                  {
667                      chars_written = fputs(unmodified_buffer,out_fh);
668                      if (chars_written != strlen(unmodified_buffer))
669                      {
670                          if (rc == RC_SUCCESS)
671                          {
672                              rc = RC_WRITE_ERROR_TEMP;
673                          }
674                      }
675                  }
676              }
677
678           } while (rc == RC_SUCCESS);
679       }
680       else
681       {
682           rc = RC_MEMORY_ALLOCATION_ERROR;
683       }
684       if (rc == RC_END_OF_FILE)
685       {
686           rc = RC_SUCCESS;
687       }
688
689       /* free all allocated buffers */
690       if (inputbuffer != NULL)
691       {
692           free(inputbuffer);
693       }
694       if (inputbuffer1 != NULL)
695       {
696           free(inputbuffer1);
697       }
698       if (unmodified_buffer != NULL)
699       {
700           free(unmodified_buffer);
701       }
702    }
703    else
704    {
705        rc = RC_OPEN_ERROR;
706    }
707    if (in_fh != NULL)
708    {
709        fclose(in_fh);
710    }
711    if (out_fh != NULL)
712    {
713        fclose(out_fh);
714    }
715    return(rc);
716 }
717