#include #include #include #include #include "uucp.h" #include "internal.h" #include #include #include "uucp.m" #include UUCP_HELP_FILE help_uucp ("uucp"); static UUCP_HELP_FILE help_system ("system"); static CONFIG_FILE f_systems (VAR_LIB_UUCP_SYSTEMS ,help_uucp ,CONFIGF_OPTIONAL|CONFIGF_MANAGED ,"uucp","uucp",0660,subsys_uucp); PUBLIC SYSTEM::SYSTEM() { speed = 38400; tbchat[0].expected.setfrom ("ogin:"); tbchat[1].expected.setfrom ("assword:"); } /* Initialise a record from a line of the Systems file */ PUBLIC SYSTEM::SYSTEM(const char *line, const SSTRING &_comment, char *err) { err[0] = '\0'; line = str_copyword (name,line); line = str_copyword (when,line); line = str_copyword (acu,line); char word[100]; line = str_copyword (word,line,sizeof(word)); speed = atoi (word); line = str_copyword (phone,line); line = str_skip(line); int nbchat = 0; while (nbchat < NBCHAT_ELM){ CHAT_ELM *e = tbchat + nbchat; line = str_copyword (word,line,sizeof(word)); if (word[0] == '\0') break; if (strcmp(word,"\"\"")==0) word[0] = '\0'; e->expected.setfrom (word); line = str_copyword (word,line,sizeof(word)); if (word[0] == '\0') break; if (strcmp(word,"\"\"")==0) word[0] = '\0'; e->send.setfrom (word); nbchat++; } comment.setfrom (_comment); comment.strip_end(); } PUBLIC void SYSTEM::write (FILE_CFG *fout) { /* #Specification: uucp / file "Systems" / comments Linuxconf is trying to keep the original comments in the file. */ comment_write (comment,fout); fprintf (fout,"%s %s %s %d %s " ,name.get(),when.get(),acu.get() ,speed,phone.get()); for (int i=0; iexpected.is_empty() || !e->send.is_empty()){ const char *expec = e->expected.get(); if (expec[0] == '\0') expec = "\"\""; const char *send = e->send.get(); if (send[0] == '\0') send = "\"\""; fprintf (fout,"%s %s ",expec,send); } } fputc ('\n',fout); } static void check_empty ( SSTRING fld, const char *msg, char *err, int &nof, int field_no) { if (fld.is_empty()){ strcat (err,msg); strcat (err," "); strcat (err,MSG_U(E_EMPTY,"must not be empty\n")); if (nof == -1) nof = field_no; } } /* Edit one system record. Return -1 if the user quit editing. Return 0 if the user accept the changes Return 1 if the user wish to delete the record. */ PUBLIC int SYSTEM::edit( PERMISSIONS &perms, POLLS &polls) { int ret = -1; DIALOG dia; dia.newf_str (MSG_U(F_UUCPSYS,"Remote system name"),name); FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_WHEN,"Schedule"),when); comb->addopt ("Any",MSG_U(M_ANY,"Your system call anytime needed")); comb->addopt ("Never",MSG_U(M_NEVER,"The other site is calling you")); comb->addopt ("8-10,14-16",MSG_U(M_EXAMPLE,"One example")); comb = dia.newf_combo (MSG_U(F_TYPE,"Transport type"),acu); comb->addopt ("ACU",MSG_U(M_MODEM,"Modem device")); comb->addopt ("Direct",MSG_U(M_DIRECT,"Null modem serial line")); comb->addopt ("TCP",MSG_U(M_UUCPTCP,"UUCP over TCP/IP")); SSTRING speedstr; baud_setfield (speed,speedstr,dia); dia.newf_str (MSG_U(F_PHONE,"Phone"),phone); POLL *poll = polls.getitem(name.get()); POLL *newpoll = NULL; if (poll == NULL){ newpoll = new POLL (name.get()); poll = newpoll; } dia.newf_str (MSG_U(F_SCHED,"Polling schedule"),poll->sched); #if 0 // Comment handling is just too simple to be useful. A full // editor is need, not a single line. dia.newf_str (MSG_U(F_COMMENT,"Comment"),comment); #endif dia.newf_title ("",MSG_U(T_LOGINSCRIPT,"Login script")); int i; for (i=0; iexpected); dia.newf_str (MSG_U(F_SEND,"Send"),e->send); } PERMISSIONS ptmp; ptmp.neverdelete(); if (!name.is_empty()){ int no = 0; PERMISSION *p; while ((p=perms.getitem(name.get(),no))!=NULL){ ptmp.add (p); } } int no_perms = ptmp.getnb()==0; // No permission record defined /* #Specification: uucp / permissions / many per site Several Permission config are possible for one site. They are differentiate with the logname entry. Linuxconf support this by always proposing few empty slots at the end of the dialog */ const int SPARE_P = 3; PERMISSION pnew[SPARE_P]; for (i=0; ilogname); USERS users; const char *uucpshell = shells_getuucpdefault(); for (int u=0; ugetshell(),uucpshell)==0){ comb->addopt(user->getname(),user->getgecos()); } } dia.newf_str (MSG_U(F_MASQUERADE,"Masquerade as"),p->myname); dia.newf_chk ("",p->mayrequest,MSG_U(F_MAYREQUEST,"May request files")); dia.newf_str (MSG_U(F_DIRREAD,"May read"),p->dirread); dia.newf_chk ("",p->maysend,MSG_U(F_MAYSEND,"May send files")); dia.newf_str (MSG_U(F_MAYWRITE,"May write"),p->dirwrite); dia.newf_str (MSG_U(F_MAYEXEC,"Available commands"),p->commands); nb_perm = dia.getnb() - tmp; // How many field per permission record } int nof = 0; while (1){ MENU_STATUS code = dia.edit(MSG_U(T_SYSTEM,"One system configuration") ,MSG_U(I_SYSTEM,"You must define how and when one\n" "system can be reached.\n") ,help_system ,nof ,MENUBUT_EDIT|MENUBUT_ACCEPT|MENUBUT_CANCEL|MENUBUT_DEL); if (code == MENU_EDIT){ int noperm = (nof - start_perm)/nb_perm; if ((nof - start_perm)%nb_perm == 1){ // EDIT on a login name field dia.save(); PERMISSION *p = ptmp.getitem(noperm); p->machine.setfrom (name); const char *logname = p->logname.get(); if (logname[0] != '\0'){ users_editone (logname,UUCP_GROUP,logname); }else{ xconf_error (MSG_U(E_EMPTYLOGNAME,"No login name")); } }else{ xconf_error (MSG_U(E_NOEDIT,"No edit on this field")); } }else if (code == MENU_CANCEL || code == MENU_ESCAPE){ break; }else if (code == MENU_DEL){ if (xconf_areyousure(MSG_U(Q_DELSYSTEM ,"Confirm deletion of uucp system"))){ ret = 1; polls.delsystem (name.get()); polls.write(); perms.delsystem (name.get()); perms.write(); break; } }else{ char err[2000]; err[0] = '\0'; nof = -1; // nof will be positionned on the first field with an error check_empty (name,MSG_U(E_NAME,"Site name"),err,nof,0); check_empty (when,MSG_U(E_SCHED,"Schedule"),err,nof,1); check_empty (acu,MSG_U(E_TRANS,"Transport type"),err,nof,2); check_empty (speedstr,MSG_U(E_SPEED,"modem speed"),err,nof,3); check_empty (phone,MSG_U(E_PHONE,"Phone"),err,nof,4); if (err[0] != '\0'){ xconf_error (MSG_U(E_SOMERRORS,"There are some errors\n%s") ,err); }else{ /* #Specification: uucp / permission record / at least one There is at least one permission record for each uucp site. Subsequent permission configs will be collected when the LOGNAME field is non empty. */ for (i=0; imachine.setfrom (name); const char *logname = p->logname.get(); if (logname[0] != '\0'){ if (!user_exist (logname)){ users_editone (logname,UUCP_GROUP,logname); } }else if (logname[0] == '\0' && i > 0){ perms.remove_del (p); ptmp.remove (p); i--; } } for (i=0; ilogname.is_empty() || (i== 0 && no_perms)){ perms.add (new PERMISSION (p)); } } speed = speedstr.getval(); poll->system.setfrom (name); if (poll->sched.is_empty()){ polls.remove_del (poll); delete newpoll; }else if (newpoll != NULL){ polls.add (newpoll); } polls.write(); perms.write(); ret = 0; break; } } } if (ret < 0) dia.restore(); return ret; } PUBLIC SYSTEM *SYSTEMS::getitem(int no) { return (SYSTEM*)ARRAY::getitem(no); } PROTECTED CONFIG_OBJ *SYSTEMS::newobj ( const char *buf, // Buffer to parse from the Permissions file const SSTRING &_comments, // Comments preceding the definition char *err) // Will contain error message or '\0' { return new SYSTEM (buf,_comments,err); } PUBLIC SYSTEMS::SYSTEMS() : CONFIG_OBJS (f_systems) { read(); } static int cmp_by_name (const ARRAY_OBJ *o1, const ARRAY_OBJ *o2) { SYSTEM *s1 = (SYSTEM*)o1; SYSTEM *s2 = (SYSTEM*)o2; return s1->name.cmp(s2->name); } PUBLIC void SYSTEMS::sort() { ARRAY::sort (cmp_by_name); } /* Edit the different systems. Return -1 if the user escape */ PUBLIC int SYSTEMS::edit( PERMISSIONS &perms, POLLS &polls) { int ret = 0; int sel = 0; while (1){ DIALOG dia; int n = getnb(); sort(); for (int i=0; iname); } dia.addwhat (MSG_U(I_ADDSYS,"Select [Add] to define one new configuration")); MENU_STATUS code = dia.editmenu ( MSG_U(T_SYSTEMS,"Edit uucp configurations") ,MSG_U(I_SYSTEMS,"Each configuration control the way\n" "your computer interact with other computers using\n" "the UUCP protocol (background file transfer)\n") ,help_uucp ,sel,0); if (code == MENU_OK){ if (n > 0){ SYSTEM *s = getitem(sel); SSTRING name(s->name); int code = manage_edit(s,s->edit(perms,polls)); if (code == 1){ PERMISSION *p; while ((p=perms.getitem(name.get()))!=NULL){ perms.remove_del (p); } } } }else if (code == MENU_ESCAPE || code == MENU_QUIT){ break; }else if (code == MENU_ADD){ SYSTEM *s = new SYSTEM; manage_edit (s,s->edit(perms,polls)); } } return ret; } void system_edit () { if (perm_rootaccess (MSG_U(P_UUCP,"to manage uucp"))){ SYSTEMS systems; PERMISSIONS perms; POLLS polls; polls.read (); perms.read (); if (systems.edit(perms,polls)==0){ perms.write(); polls.write(); systems.write(); } } }