#include #include #include "misc.h" #include #include #include #include // #Specbeg: CONFIG_FILE_LISTER / sample /* This sample code illustrate how dynamic (configuration dependant) configuration file are handled for system profile versioning. The trick is to use a CONFIG_FILE_LISTER object and to override the CONFIG_FILE::extract() member function of the configuration file providing the list of dynamic configuration file. For this sample, we create a CONFIG_FILE /tmp/file.list, which contains one file path per line. Note that the f_list CONFIG_FILE belongs to sub-system sample like all the dynamic configuraion file, so they are archived/extracted together. Note also that the sample_list() function create new CONFIG_FILE object. The CONFIG_FILE_LISTER framework will delete them later. For extraction to work, we must define a new CONFIG_FILE classe which overrire the CONFIG_FILE::extract(SSTREAM &) function. */ static const char subsys_sample[]="sample"; static LINUXCONF_SUBSYS sub (subsys_sample,"This is a sample sub-system"); class CONFIG_FILE_SAMPLE: public CONFIG_FILE{ public: CONFIG_FILE_SAMPLE(const char *_path, HELP_FILE &_help, int _opt, const char *_subsys) : CONFIG_FILE (_path,_help,_opt,_subsys) { } int extract (SSTREAM &ss); }; static CONFIG_FILE_SAMPLE f_list ("/tmp/file.list",help_nil,CONFIGF_OPTIONAL,subsys_sample); static void sample_list() { FILE_CFG *fin = f_list.fopen ("r"); if (fin != NULL){ char path[PATH_MAX]; while (fgets_strip(path,sizeof(path)-1,fin,NULL)!=NULL){ if (path[0] != '\0'){ new CONFIG_FILE (path,help_nil,CONFIGF_OPTIONAL,subsys_sample); } } fclose (fin); } } int CONFIG_FILE_SAMPLE::extract (SSTREAM &ss) { CONFIG_FILE::extract (ss); sample_list(); return 0; } static CONFIG_FILE_LISTER lister(sample_list); static void sample_listconfig() { xconf_notice ( "We will present the list of all configuration file\n" "and we will see /tmp/file.list and its children in the list\n" "\n" "Edit this file and add various file path to it\n" ); configf_list(); xconf_notice ("Now, we will archive the sample sub-system"); SSTRINGS tb; tb.add(new SSTRING(subsys_sample)); SSTREAM_FILE ssout(stdout); configf_archive (tb,"/tmp/cfgarchive","--arch",ssout,true); xconf_notice ("Now we will delete /tmp/file.list\n" "and trigger an extraction"); f_list.unlink(); xconf_notice ("/tmp/file.list is deleted"); configf_extract (tb,"/tmp/cfgarchive","--extr"); } // #Specend: // #Specbeg: CONTEXT_LOCK / sample /* The CONTEXT_LOCK class is used to get exclusive access to some area in Linuxconf or a module. This is fully multi-user. This means that two Linuxconf instances will cooperate on this. The class is very easy to use. It is also interactive. The goal is to avoid tedious code repetition here and there. The following sample presents two usage. One is locking a whole system and the other is locking a specific record. The trick is to use the one or two parameters constructor. */ static void sample_context_lock() { DIALOG_MENU dia; static const char *tb[]={ "test", "global lock", "", "lock on record1", "", "lock on record2", NULL }; dia.new_menuitems (tb); int nof = 0; while (1){ MENU_STATUS code = dia.editmenu ("context-lock" ,"The first option shows the CONTEXT_LOCK with one key\n" "The second and third test the lock with two keys" ,help_nil,nof,0); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else if (nof == 0){ CONTEXT_LOCK l("sample"); if (l.isok()){ xconf_notice ("We have exclusive access"); } }else if (nof == 1 || nof == 2){ char tmp[10]; sprintf (tmp,"record%d",nof); CONTEXT_LOCK l("sample",tmp); if (l.isok()){ xconf_notice ("We have exclusive access on %s",tmp); } } } } // #Specend: int main (int argc, char *argv[]) { argc = dialog_parseuioptions (argc, argv); linuxconf_loadmsg ("linuxconf",PACKAGE_REV); translat_checkmissing(); dialog_clear(); if (argc == 2){ if (strcmp(argv[1],"list-config")==0){ sample_listconfig(); }else if (strcmp(argv[1],"context-lock")==0){ sample_context_lock(); } }else{ fprintf (stderr ,"list-config\n" "context-lock\n"); } return 0; }