1 /*****
2  *       Xnee's Not an Event Emulator
3  *
4  * Xnee enables recording and replaying of X protocol data
5  *
6  *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004,
7  *                 2005, 2006, 2007, 2009, 2010
8  *                 Henrik Sandklef
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 3
13  * of the License, or any later version.
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Boston,
24  * MA  02110-1301, USA.
25  ****/
26 
27 
28 
29 
30 
31 
32 /* Standard includes */
33 #include <stdio.h>
34 
35 #include "libxnee/xnee.h"
36 #include "libxnee/print.h"
37 #include "libxnee/xnee_dl.h"
38 #include "libxnee/xnee_sem.h"
39 #include "libxnee/xnee_setget.h"
40 #include "libxnee/xnee_resolution.h"
41 #include "libxnee/xnee_resource.h"
42 #include "libxnee/xnee_grab.h"
43 #include "libxnee/xnee_km.h"
44 #include "libxnee/datastrings.h"
45 #include "libxnee/xnee_range.h"
46 #include "libxnee/xnee_session.h"
47 #include "libxnee/xnee_alloc.h"
48 
49 
50 static struct xnee_ranges  myxrs           ;
51 static int    need_init          =  1      ;
52 static int    added_reparent     =  0      ;
53 struct xnee_ranges *xrs          = &myxrs  ;
54 
55 static int
56 xnee_add_to_list2(xnee_data *xd, int type, int ev);
57 
58 int
59 xnee_add_range (xnee_data* xd, int type,
60 		int start, int stop);
61 int
62 xnee_rem_from_list(xnee_data *xd, int type, int ev);
63 
64 static int
xnee_do_workaround(xnee_data * xd)65 xnee_do_workaround(xnee_data *xd)
66 {
67   int ret = XNEE_OK;
68   int active_state;
69 
70   if ( xnee_is_type_nr_set(xd, XNEE_DELIVERED_EVENT, ReparentNotify))
71     {
72       xnee_set_new_window_pos(xd);
73     }
74   else
75     {
76       active_state = xd->record_setup->active;
77 
78       xnee_add_to_list2(xd, XNEE_DELIVERED_EVENT, ReparentNotify);
79       /* Reset active state, since we don't want to record anything
80        * if nothing specified.
81        * We don't want to record the ReparentNotify (as added to
82        * achieve new window pos only)....
83        */
84       xd->record_setup->active = active_state ;
85       added_reparent = 1 ;
86     }
87   return ret;
88 }
89 
90 static int
xnee_undo_workaround(xnee_data * xd)91 xnee_undo_workaround(xnee_data *xd)
92 {
93   int ret = XNEE_OK;
94   int w_pos= xnee_get_new_window_pos(xd);
95 
96   if (added_reparent)
97     {
98       xnee_rem_from_list(xd, XNEE_DELIVERED_EVENT, ReparentNotify);
99       added_reparent = 0 ;
100     }
101 
102   if (w_pos > 0)
103     {
104       xnee_unset_new_window_pos(xd);
105     }
106 
107   return ret;
108 }
109 
110 
111 /**************************************************************
112  *                                                            *
113  * xnee_null_range                                            *
114  *                                                            *
115  *                                                            *
116  **************************************************************/
117 void
xnee_null_range(XRecordRange * range)118 xnee_null_range ( XRecordRange *range)
119 {
120   memset (range, 0, sizeof(XRecordRange));
121   /* There seems to be something spooky about setting
122      errors to first=last=0
123      This solves the X server crashes that has been around for a while */
124   /*
125   range->errors.first = BadCursor;
126   range->errors.last  = BadCursor;
127   */
128 }
129 
130 static int
xnee_bsort(int * numbers,int size)131 xnee_bsort(int *numbers, int size)
132 {
133   int i;
134   int j;
135   int temp;
136 
137   for (i = (size - 1); i >= 0; i--)
138   {
139     for (j = 1; j <= i; j++)
140     {
141        if (numbers[j-1] > numbers[j])
142        {
143           temp = numbers[j-1];
144           numbers[j-1] = numbers[j];
145           numbers[j] = temp;
146        }
147     }
148   }
149   return XNEE_OK;
150 }
151 
152 static int
xnee_bsort_all(void)153 xnee_bsort_all(void)
154 {
155    int i ;
156    for (i=0;i<XNEE_NR_OF_TYPES;i++)
157      {
158        xnee_bsort (xrs->type[i].data, xrs->type[i].index);
159      }
160   return XNEE_OK;
161 }
162 
163 
164 static int
xnee_init_list(struct xnee_range * xr,int size)165 xnee_init_list(struct xnee_range *xr, int size)
166 {
167 /*   printf ("\t'%s'  need=%d\n", */
168 /* 	  __func__, need_init); */
169   xr->index = 0;
170   xr->size  = size;
171   xr->data  = (int*) malloc (xr->size*sizeof(int));
172 /*   printf (" xr->data = %d\n", xr->data); */
173   return XNEE_OK;
174 }
175 
176 int
xnee_free_ranges(xnee_data * xd)177 xnee_free_ranges(xnee_data *xd)
178 {
179    int i ;
180 
181    xnee_verbose((xd, " -- xnee_free_ranges\n"));
182 
183    for (i=0;i<XNEE_NR_OF_TYPES;i++)
184    {
185      XNEE_FREE_AND_NULL(xrs->type[i].data);
186      xrs->type[i].data  = NULL;
187      xrs->type[i].index = 0;
188    }
189    need_init = 1 ;
190 
191    return XNEE_OK;
192 }
193 
194 int
xnee_init_ranges()195 xnee_init_ranges()
196 {
197    int i ;
198    xrs->alloc_size = 5;
199 
200 /*    printf ("--->'%s'  init ranges  need=%d\n", */
201 /* 	   __func__, need_init); */
202 
203    for (i=0;i<XNEE_NR_OF_TYPES;i++)
204    {
205      xnee_init_list (&xrs->type[i], xrs->alloc_size);
206    }
207    need_init = 0 ;
208 /*    printf ("<---'%s'  init ranges  need=%d\n", */
209 /* 	   __func__, need_init); */
210    return XNEE_OK;
211 }
212 
213 
214 int
xnee_refresh_ranges(xnee_data * xd)215 xnee_refresh_ranges(xnee_data *xd)
216 {
217   xnee_verbose((xd, "-->xnee_refresh_ranges\n"));
218   xnee_free_ranges(xd);
219   xnee_init_ranges();
220   xrs->nr_of_data = 0;
221   xnee_verbose((xd, "<--xnee_refresh_ranges\n"));
222   return XNEE_OK;
223 }
224 
225 int
xnee_print_list(void)226 xnee_print_list(void)
227 {
228    int i ;
229    int j ;
230 
231    for (i=0;i<XNEE_NR_OF_TYPES;i++)
232    {
233       printf ("%d:[", i);
234       for (j=0; j<xrs->type[i].index ;j++)
235       {
236          printf ("%.3d", xrs->type[i].data[j]);
237 
238          if (j!=xrs->type[i].index-1)
239             printf (",");
240       }
241       printf ("]\n");
242    }
243    printf ("\n");
244    return XNEE_OK;
245 }
246 
247 
248 static int
xnee_add_to_list2(xnee_data * xd,int type,int ev)249 xnee_add_to_list2(xnee_data *xd, int type, int ev)
250 {
251    int i ;
252    struct xnee_range *xrp;
253 
254    /* An item is added, set recording active */
255    xd->record_setup->active = 1;
256 
257    if (type==XNEE_EVENT)
258      {
259        if ((ev>=KeyPress)&&(ev<=MotionNotify))
260 	 {
261 	   type=XNEE_DEVICE_EVENT;
262 	 }
263        else
264 	 {
265 	   type=XNEE_DELIVERED_EVENT;
266 	 }
267      }
268    xrp = &xrs->type[type];
269 
270    if (need_init==1)
271      {
272        xnee_init_ranges();
273      }
274 
275    for (i=0;i<xrp->index;i++)
276      {
277        if (xrp->data[i]==ev)
278 	 {
279 	   return XNEE_OK;
280 	 }
281      }
282 
283    if (xrp->index >=(xrp->size-1) )
284    {
285       xrp->size+=xrp->size;
286 
287       xrp->data = (int*) realloc (xrp->data,
288                                   xrp->size*sizeof(int));
289       if (xrp->data==NULL)
290       {
291          fprintf (stderr, "  PANIC in xnee_add_to_list2 ....\n") ;
292 	 fflush(stdout);
293 	 return XNEE_MEMORY_FAULT;
294       }
295    }
296    xrp->data[xrp->index++]=ev;
297 
298    return XNEE_OK;
299 }
300 
301 /**************************************************************
302  *                                                            *
303  * xnee_add_range_str                                         *
304  *                                                            *
305  *                                                            *
306  **************************************************************/
307 int
xnee_add_range_str(xnee_data * xd,int type,char * range)308 xnee_add_range_str (xnee_data *xd, int type, char *range)
309 {
310   char start_str[XNEE_RANGE_STRING_SIZE] ;
311   char *second;
312   int start=0;
313   int stop=0;
314   int str_len=0;
315   int ret=0;
316   int i ;
317   xnee_verbose((xd, " --> add_range_str (%p, %d, %s)\n",
318 		(void*)xd,type, range));
319   str_len=strspn(range, "1234567890-");
320 
321 
322   if ( str_len > XNEE_RANGE_STRING_SIZE )
323     {
324       fprintf (stderr, "The string you wanted to add is too long\n");
325       fprintf (stderr, "Ranges can't be longer then %d characters\n",
326 	       XNEE_RANGE_STRING_SIZE);
327       return -1;
328     }
329 
330   if (str_len==0)
331     {
332       str_len=
333 	strspn(range,
334 	       "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_");
335 	  strncpy(start_str,range,str_len);
336 	  start_str[str_len]='\0';
337 	  start=xnee_data2int (type, start_str);
338 	  if (start==-1)
339 	    {
340 	      fprintf(stderr,
341 		      "Could not convert \"%s\" to an integer\nleaving",
342 		      start_str);
343 	      return -1;
344 	    }
345     }
346   else
347     {
348       strncpy(start_str,range,str_len);
349       start_str[str_len]='\0';
350       sscanf(start_str,"%d",&start);
351     }
352   xnee_verbose((xd,
353 		" --  add_range_str first string=\"%s\" (%d)\n",
354 		start_str, start));
355 
356 
357   second=strchr ( range, '-' ) ;
358   if (second)
359     {
360       int ret;
361       second++;
362       ret=sscanf(second,"%d",&stop);
363       if (ret==0)
364 	{
365 	  stop=xnee_data2int (type, second);
366 	  if (stop==-1)
367 	    {
368 	      fprintf(stderr,
369 		      "Could not convert \"%s\" to an integer\nleaving",
370 		      second);
371 	      return -1;
372 	    }
373 	}
374       xnee_verbose((xd, " --  add_range_str second string=\"%s\"   ret=%d\n",
375                     second, ret));
376     }
377 
378   xnee_verbose((xd, " --  add_range_str 1 %d %d \n" ,
379 		start, stop));
380   if ( (start>=0) && (stop>=0) )
381     {
382       if ( (start!=stop) && (start<stop) )
383 	{
384 	  for (i=start;i<=stop;i++)
385 	    {
386 	      ret = xnee_add_to_list2(xd, type, i);
387 	    }
388 	}
389       else if (start!=0)
390 	{
391 	  xnee_verbose((xd, " --  add_range_str 4\n" ));
392 	  ret = xnee_add_to_list2(xd, type, start);
393 	}
394       else if ( (start==0) && (stop==0) )
395 	{
396 	  ret = XNEE_OK;
397 	}
398       else
399 	{
400 	  ret = XNEE_RANGE_FAILURE ;
401 	}
402     }
403 
404   xnee_verbose((xd, " <-- add_range_str (%p, %d, %s) max range=%d\n",
405 		(void*)xd,type, range, xnee_get_max_range(xd)));
406 
407   return (ret);
408 }
409 
410 
411 static int
xnee_device_as_delivered(xnee_data * xd)412 xnee_device_as_delivered(xnee_data *xd)
413 {
414   int ret_val = 0;
415 
416   if (xd!=NULL)
417     {
418       if (  (xd->x_vendor_name != NULL ) &&
419 	    (strstr(xd->x_vendor_name, "X.Org") ))
420 	{
421 	  if ( ( xd->x_version_major == 1 ) &&
422 	       ( xd->x_version_minor >= 6 ) &&
423 	       ( xd->x_version_minor < 9 ) )
424 	    {
425 	      ret_val = 1;
426 	    }
427 	}
428     }
429   return ret_val;
430 }
431 
432 
433 
434 static int
is_dangerous_xserver(xnee_data * xd)435 is_dangerous_xserver(xnee_data *xd)
436 {
437   int ret_val = 1;
438   if (xd==NULL)
439     {
440       return XNEE_MEMORY_FAULT;
441     }
442 
443   if (xd->x_vendor_name==NULL)
444     {
445       xnee_set_x_server_version(xd);
446     }
447 
448   if (strstr(xd->x_vendor_name, "X.Org") )
449     {
450 
451       if (  ( ( xd->x_version_major == 7 ) ||
452 	      ( xd->x_version_major == 1 ) ) &&
453 	    ( xd->x_version_minor >= 1 ) )
454 	{
455 	  ret_val = 0;
456 	}
457     }
458 return ret_val;
459 }
460 
461 
462 
463 /**************************************************************
464  *                                                            *
465  * xnee_add_range                                             *
466  *                                                            *
467  *                                                            *
468  **************************************************************/
469 int
xnee_add_range(xnee_data * xd,int type,int start,int stop)470 xnee_add_range (xnee_data* xd,
471 		     int type,
472 		     int start,
473 		     int stop)
474 {
475   XRecordRange *range;
476   int max_index=0;
477   int alloc_nr=0;
478 
479   XRecordRange *r_range;
480   xnee_verbose((xd, "---> xnee_add_range %d %d %d\n", type, start, stop));
481 
482   /* increment the counter to ensure we allocate enough memory */
483   alloc_nr=xd->xnee_info.data_ranges[type]  ;
484   max_index=xnee_get_max_range(xd) - 1 ;
485 
486   xnee_verbose((xd, "  MAX %d ALLOC %d\n", max_index, alloc_nr));
487 
488   if (alloc_nr>max_index)
489   {
490      xnee_verbose((xd, " -- Allocating a new range of size %d\n",
491                    alloc_nr+1));
492 
493      if ( alloc_nr == 0 )
494      {
495         xd->record_setup->range_array =
496            (XRecordRange**) Xcalloc (1, sizeof(XRecordRange*));
497      }
498      else
499      {
500         xd->record_setup->range_array =
501            (XRecordRange**) Xrealloc (xd->record_setup->range_array,
502                                       (alloc_nr+1)*sizeof(XRecordRange*));
503      }
504      r_range =  XRecordAllocRange();
505 
506      xnee_null_range (r_range);
507      xd->record_setup->range_array[alloc_nr] = r_range;
508   }
509 
510 
511   /* is it single value */
512   if (stop==0)
513     {
514       stop=start;
515     }
516   xnee_verbose((xd,
517                 "Adding %d range %d - %d at range %d\n",
518                 type, start, stop, alloc_nr));
519 
520   range = xd->record_setup->range_array[alloc_nr];
521 
522   if ( type == XNEE_DELIVERED_EVENT )
523     {
524       range->delivered_events.first = start;
525       range->delivered_events.last = stop;
526 
527 
528       if ( is_dangerous_xserver(xd) )
529 	{
530 	  fprintf(stderr, "Workaround: Adding some errors to recored to prevent crash\n");
531 	  fprintf(stderr, "            You can ignore this message\n");
532 	  /* Workaround for problem with crashing X server */
533 	     xd->xnee_info.data_ranges[XNEE_ERROR]++;
534 	     range->errors.first = BadCursor;
535 	     range->errors.last = BadCursor;
536 	}
537     }
538   else if ( type == XNEE_REQUEST )
539     {
540       range->core_requests.first = start;
541       range->core_requests.last = stop;
542     }
543   else if ( type == XNEE_ERROR )
544     {
545       range->errors.first = start;
546       range->errors.last = stop;
547 
548       /* Workaround for problem with crashing X server*/
549       range->delivered_events.first =33 ;
550       range->delivered_events.last = 33;
551       xd->xnee_info.data_ranges[XNEE_DELIVERED_EVENT]++;
552     }
553   else if ( type == XNEE_REPLY )
554     {
555       range->core_replies.first = start;
556       range->core_replies.last = stop;
557     }
558   else if ( type == XNEE_EXT_REQUEST_MAJOR )
559     {
560       range->ext_requests.ext_major.first = start;
561       range->ext_requests.ext_major.last = stop;
562     }
563   else if ( type == XNEE_EXT_REQUEST_MINOR )
564     {
565       range->ext_requests.ext_minor.first = start;
566       range->ext_requests.ext_minor.last = stop;
567     }
568   else if ( type == XNEE_EXT_REPLY_MAJOR )
569     {
570       range->ext_replies.ext_major.first = start;
571       range->ext_replies.ext_major.last = stop;
572     }
573   else if ( type == XNEE_EXT_REPLY_MINOR )
574     {
575       range->ext_replies.ext_minor.first = start;
576       range->ext_replies.ext_minor.last = stop;
577     }
578   else if ( type == XNEE_DEVICE_EVENT )
579     {
580       range->device_events.first = start;
581       range->device_events.last = stop;
582 
583       /*
584        * WORKAROUND
585        *
586        *   xnee doesn't record on some servers
587        *   unless device evs are added as deliv. evs  :(
588        *
589        */
590       if ( xnee_device_as_delivered(xd))
591       {
592 	fprintf(stderr, "Workaround: Adding your device events as delivered events to get them recorded.\n");
593 	fprintf(stderr, "            You can ignore this message\n");
594 	xnee_add_range(xd,
595 		       XNEE_DELIVERED_EVENT,
596 		       start ,
597 		       stop);
598       }
599       else
600 	{
601 	  /* the work around above should probably be removed any time ... errrh */
602 	  fprintf(stderr, "NOTIFICATION: If you have problem with Xnee and recording device events: File a bug report including this text.\n");
603 	}
604 
605     }
606 
607 
608   /*
609    * Used when debugging
610    * print_data_range_count (xnee_info, rec_range);
611    *
612    */
613   xd->xnee_info.data_ranges[type]++;
614   xnee_verbose((xd, "<--- xnee_add_range\n"));
615 
616 /*   xnee_record_print_record_range(xd, stderr); */
617 
618   return (XNEE_OK);
619 }
620 
621 
622 /**************************************************************
623  *                                                            *
624  * xnee_parse_range                                           *
625  *                                                            *
626  *                                                            *
627  **************************************************************/
628 int
xnee_parse_range(xnee_data * xd,int type,char * range)629 xnee_parse_range (xnee_data *xd,int type, char *range)
630 {
631   char buf[DATA_NAME_SIZE_MAX];
632   int next;
633   int ret=0;
634   int range_len=strlen(range);
635 
636 /*  */
637 
638   xnee_verbose ((xd, "int arg=%p\n", (void*)xd));
639   xnee_verbose ((xd, "nt arg=%d\n", type));
640   xnee_verbose ((xd, "string arg=%s\n", range));
641 
642   while ( 1 )
643     {
644       next=strspn (range, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_");
645       if (next==0)
646 	{
647 	  ret = XNEE_RANGE_FAILURE;
648 	  break;
649 	}
650       strncpy(buf,range,next);
651       buf[next]='\0';
652       range+=next+1;
653       range_len=range_len - next - 1;
654       xnee_verbose((xd, " -- calling xnee_add_range_str (%p, %d, %s) \n" , (void*)xd, type, buf));
655 
656       ret=xnee_add_range_str (xd, type, buf);
657 
658       if (ret == XNEE_RANGE_FAILURE )
659 	{
660 	  ret = XNEE_RANGE_FAILURE;
661 	  break;
662 	}
663       if (range_len<=0)
664 	{
665 	  break;
666 	}
667       if (ret!=XNEE_OK) return (ret);
668     }
669 
670   xnee_verbose((xd, "<-- parse_range()\n"));
671   return ret;
672 }
673 
674 
675 
676 
677 
678 int
xnee_get_nr_of_data(int type)679 xnee_get_nr_of_data (int type)
680 {
681    if (xrs->type==NULL)
682      {
683        return -1;
684      }
685    else
686      {
687        /*
688 	* We're not going to record if only ReparentNotify are recorded
689 	*/
690        if ( ( type == XNEE_DELIVERED_EVENT )
691 	    &&
692 	    ( xrs->type[type].index == 1)
693 	    &&
694 	    ( xrs->type[type].data[0] == ReparentNotify))
695 	 {
696 	   return 0;
697 	 }
698        else
699 	 {
700 	   return xrs->type[type].index;
701 	 }
702      }
703 }
704 
705 int *
xnee_get_data(int type)706 xnee_get_data (int type)
707 {
708    if (xrs->type==NULL)
709      {
710        return NULL;
711      }
712    else
713      {
714        return xrs->type[type].data;
715      }
716 }
717 
718 int
xnee_is_type_nr_set(xnee_data * xd,int type,int nr)719 xnee_is_type_nr_set(xnee_data *xd, int type, int nr)
720 {
721   int i ;
722 
723   xnee_verbose((xd, " -- xnee_is_type_nr_set\n"));
724   for (i=0; i<xrs->type[type].index ;i++)
725     {
726       if ( xrs->type[type].data[i] == nr )
727 	{
728 	  return True;
729 	}
730     }
731 
732   return False;
733 }
734 
735 
736 int
xnee_set_ranges(xnee_data * xd)737 xnee_set_ranges(xnee_data *xd)
738 {
739    int i ;
740    int j ;
741    int first = -1;
742    int last  = -1;
743    int this  ;
744 
745 
746    xnee_bsort_all();
747 
748    if (xnee_is_replayer(xd))
749      {
750        xnee_undo_workaround(xd);
751        xnee_do_workaround(xd);
752      }
753 
754    for (j=0; j<XNEE_NR_OF_TYPES ;j++)
755      {
756       first = -1;
757       last  = -1;
758 
759       for (i=0; i<xrs->type[j].index ;i++)
760 	{
761 
762 	  this = xrs->type[j].data[i] ;
763 
764 	  if (first == -1)
765 	    {
766 	      first=this;
767 	      last=this;
768 	    }
769 	  else if ( this == last + 1 )
770 	    {
771 	      last = this;
772 	    }
773 	  else
774 	    {
775 	      xnee_add_range (xd, j,
776 			      first,
777 			      last);
778 
779 	      first=this;
780 	      last=this;
781 	    }
782 	}
783       if (first!=-1)
784 	{
785 	  if (last!=-1)
786 	    {
787 	      xnee_add_range (xd, j,
788 			      first,
789 			      last);
790 	    }
791 	  else
792 	    {
793 	      xnee_add_range (xd, j,
794 			      first,
795 			      first);
796 	    }
797 	}
798    }
799 
800    return XNEE_OK;
801 }
802 
803 
804 
805 int
xnee_rem_from_list(xnee_data * xd,int type,int ev)806 xnee_rem_from_list(xnee_data *xd, int type, int ev)
807 {
808    int i ;
809    int j ;
810 
811    struct xnee_range *xrp;
812 
813    xnee_verbose((xd, " -- xnee_rem_from_list\n"));
814 
815    if (need_init==1)
816      {
817        return XNEE_OK;
818      }
819 
820    xrp = &xrs->type[type];
821 
822 
823    for (i=0;i<xrp->index;i++)
824    {
825       if ( xrp->data[i] == ev )
826       {
827          for (j=i;j<xrp->index;j++)
828          {
829             if (j==xrp->index-1)
830             {
831                xrp->data[j]=0;
832             }
833             else
834             {
835                xrp->data[j]=xrp->data[j+1];
836             }
837          }
838          xrp->index--;
839       }
840    }
841 
842    return XNEE_OK;
843 }
844 
845 
846 int*
xnee_get_list(int type)847 xnee_get_list(int type)
848 {
849    if (need_init==1)
850       return NULL;
851 
852    if (type==0)
853    {
854       return xrs->type[type].data;
855    }
856    return XNEE_OK;
857 }
858 
859 
860 
861 int
xnee_rem_data_from_range_str(xnee_data * xd,int type,char * name)862 xnee_rem_data_from_range_str (xnee_data *xd,
863                               int type,
864                               char *name)
865 {
866    int rem_data ;
867    int my_type;
868 
869    if (type == -1)
870      {
871        rem_data = xnee_data2int_special(&my_type, name);
872        type = my_type ;
873      }
874    else
875      {
876        rem_data = xnee_data2int(type, name);
877      }
878 
879    if (rem_data == -1)
880    {
881       return -1;
882    }
883 
884    xnee_verbose ((xd, "xnee range removing : %d of type %d\n",
885 		  rem_data, type ));
886    xnee_rem_from_list(xd, type, rem_data);
887 
888 
889    return XNEE_OK;
890 }
891 
892 
893 
894 
895