@@ -163,6 +163,132 @@ int ScheduleEditLineOperations(char *filename, Bundle *bp, Attributes a, Promise
163163 return true;
164164}
165165
166+ /*****************************************************************************/
167+
168+ Bundle * MakeTemporaryBundleFromTemplate (Attributes a , Promise * pp )
169+ {
170+ char bundlename [CF_MAXVARSIZE ], buffer [CF_BUFSIZE ];
171+ char * sp , * promiser , context [CF_BUFSIZE ] = "any" ;
172+ Bundle * bp ;
173+ Promise * np ;
174+ SubType * tp ;
175+ FILE * fp ;
176+ int level = 0 , size , lineno = 0 ;
177+ Item * ip , * lines = NULL ;
178+
179+ snprintf (bundlename , CF_MAXVARSIZE , "temp_cf_bundle_%s" , CanonifyName (a .template ));
180+
181+ bp = xcalloc (1 , sizeof (Bundle ));
182+ bp -> name = xstrdup (bundlename );
183+ bp -> type = xstrdup ("edit_line" );
184+ bp -> args = NULL ;
185+ bp -> next = NULL ;
186+
187+ tp = AppendSubType (bp , "insert_lines" );
188+
189+ // Now parse the template file
190+
191+ if ((fp = fopen (a .template ,"r" )) == NULL )
192+ {
193+ cfPS (cf_error , CF_INTERPT , "" , pp , a , " !! Unable to open template file \"%s\" to make \"%s\"" , a .template , pp -> promiser );
194+ return NULL ;
195+ }
196+
197+ while (!feof (fp ))
198+ {
199+ buffer [0 ] = '\0' ;
200+ fgets (buffer , CF_BUFSIZE - 1 , fp );
201+ lineno ++ ;
202+
203+ // Check closing syntax
204+
205+ // Get Action operator
206+ if (strncmp (buffer , "[%CFEngine" , strlen ("[%CFEngine" )) == 0 )
207+ {
208+ char operator [CF_BUFSIZE ], brack [CF_SMALLBUF ];
209+
210+ sscanf (buffer + strlen ("[%CFEngine" ), "%1024s %s" , operator , brack );
211+
212+ if (strcmp (brack , "%]" ) != 0 )
213+ {
214+ cfPS (cf_error , CF_INTERPT , "" , pp , a , " !! Template file \"%s\" syntax error, missing close \"%%]\" at line %d" , a .template , lineno );
215+ return NULL ;
216+ }
217+
218+ if (strcmp (operator , "BEGIN" ) == 0 )
219+ {
220+ // start new buffer
221+
222+ if (++ level > 1 )
223+ {
224+ cfPS (cf_error , CF_INTERPT , "" , pp , a , " !! Template file \"%s\" contains nested blocks which are not allowed, near line %d" , a .template , lineno );
225+ return NULL ;
226+ }
227+
228+ continue ;
229+ }
230+
231+ if (strcmp (operator , "END" ) == 0 )
232+ {
233+ // install buffer
234+ level -- ;
235+ }
236+
237+ if (strcmp (operator + strlen (operator )- 2 , "::" ) == 0 )
238+ {
239+ * (operator + strlen (operator )- 2 ) = '\0' ;
240+ strcpy (context , operator );
241+ continue ;
242+ }
243+
244+ // In all these cases, we should start a new promise
245+
246+ promiser = NULL ;
247+ size = 0 ;
248+
249+ for (ip = lines ; ip != NULL ; ip = ip -> next )
250+ {
251+ size += strlen (ip -> name );
252+ }
253+
254+ sp = promiser = xcalloc (1 , size + 1 );
255+
256+ for (ip = lines ; ip != NULL ; ip = ip -> next )
257+ {
258+ int len = strlen (ip -> name );
259+ strncpy (sp , ip -> name , len );
260+ sp += len ;
261+ }
262+
263+ * (sp - 1 ) = '\0' ; // StripTrailingNewline(promiser) and terminate
264+
265+ np = AppendPromise (tp , promiser , (Rval ) { NULL , CF_NOPROMISEE }, context , bundlename , "edit_line" );
266+ AppendConstraint (& (np -> conlist ), "insert_type" , (Rval ) { xstrdup ("preserve_block" ), CF_SCALAR }, "any" , false);
267+
268+ DeleteItemList (lines );
269+ free (promiser );
270+ lines = NULL ;
271+ }
272+ else
273+ {
274+ if (level > 0 )
275+ {
276+ AppendItem (& lines , buffer , NULL );
277+ }
278+ else
279+ {
280+ //install independent promise line
281+ StripTrailingNewline (buffer );
282+ np = AppendPromise (tp , buffer , (Rval ) { NULL , CF_NOPROMISEE }, context , bundlename , "edit_line" );
283+ AppendConstraint (& (np -> conlist ), "insert_type" , (Rval ) { xstrdup ("preserve_block" ), CF_SCALAR }, "any" , false);
284+ }
285+ }
286+ }
287+
288+ fclose (fp );
289+ return bp ;
290+ }
291+
166292/***************************************************************************/
167293/* Level */
168294/***************************************************************************/
0 commit comments