#include #include #include #include #include #include #include #include #include #include "fstab.h" #include "fstab.m" #include extern FSTAB_HELP_FILE help_mount; static FSTAB_HELP_FILE help_swap ("swap"); static FSTAB_HELP_FILE help_quotacheck ("quotacheck"); PRIVATE void FSTAB::fixroot(FSTAB_ENTRY *root, SSTRING &status) { const char *errmsg = NULL; struct stat64 roots; if (stat64("/",&roots) < 0){ errmsg = "directory /"; }else{ DIR *dp = opendir("/dev"); if (dp == NULL){ errmsg = "/dev"; }else{ const char *source = root->getsource(); if (strncasecmp(source,"LABEL=",6)==0){ const char *p = partition_findfromlabel(source+6); if (p != NULL) source = p; } char name[PATH_MAX+1]; strcpy(name,"/dev/"); struct dirent *dir; while ((dir = readdir(dp))!=NULL) { strcpy(name+5,dir->d_name); struct stat64 s; if (stat64(name,&s) < 0){ errmsg = name; break; }else if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == roots.st_dev){ if (strcmp(source,name)!=0){ root->setsource (name); status.appendf(MSG_U(N_ROOTDEF ,"The root device has been changed to %s\n\n") ,name); } break; } } closedir(dp); } } if (errmsg){ xconf_error (MSG_U(E_CANTVLD,"Can't validate the root entry\n" "of your /etc/fstab file for the following\n" "reason:\n" "\n" "%s: %s"),errmsg,strerror(errno)); } } /* Do some sanity check on one entry of /etc/fstab Return -1 if any error that can't be fixed. */ PUBLIC int FSTAB_ENTRY::check() { /* #Specification: fstab / entry / checking fsconf make sure the entry has a valid (existing mount point). It check if it exist and it check if it is a directory. If it does not exist, the user is allowed to create it. */ int ret = 0; if (is_valid() && !is_swap()){ struct stat64 st; const char *path = mpoint.get(); ret = -1; if (path[0] == '\0'){ xconf_error (MSG_U(E_NOMNTPT ,"You must specify a " "mount point(directory)\n" "for entry %s\n"),source.get()); }else if (context_isroot() && stat64(path,&st)==-1){ char buf[1000]; sprintf (buf,MSG_U(Q_EXISTMNT,"Mount point %s\n" "does not exist.\n" "Do you want to create it ?\n") ,path); if (dialog_yesno(MSG_U(T_CANTMOUNT,"Can't mount") ,buf ,help_mount) == MENU_YES){ file_mkdirp (path,"root","root",0755); ret = 0; } }else if (context_isroot() && !S_ISDIR(st.st_mode)){ xconf_error (MSG_U(E_ISNOTDIR ,"%s is not a directory\n" "please pick a different mount point\n") ,path); }else if (loopdev.is_filled() && !bool_opt.loop){ xconf_error (MSG_U(E_LOOPDEV ,"You can't specify a loop device\n" "unless you enable the loop option.")); ret = -1; }else{ ret = 0; } } return ret; } /* Return the root device */ PUBLIC const char *FSTAB::getrootdev() { const char *ret = ""; for (int i=0; igetmpoint(); if (strcmp(mpoint,"/")==0){ ret = e->getsource(); break; } } return ret; } /* Make sure the /etc/fstab file contain minimally accurate entries. The caller will have to save it by checking was_modified(). */ PUBLIC void FSTAB::check() { const char *NO_SWAP_NEEDED = "# Please no swap"; /* #Specification: /etc/fstab / minimal check The /etc/fstab is checked to make sure is contain the basic entries requiered to run successfully a Linux system. -It check for the root fs, both for presence and accuracy. For example, if the user reorganise its drive (linux was hdb and is now hda), or copy a working (configured) installation to another disk/partition, this utility will automagically fix the root entry. -Check the /proc entry. It needs to be there. -Check for minimally a swap space. If there is none the user will be prompt to create one. The user will have the choice to say "No don't bother to ask again, I don't need a swap". A special comment line will be added to /etc/fstab to prevent linuxconf from asking again and again. */ bool swap_seen = false; bool proc_seen = false; bool no_swap_seen = false; SSTRING status; for (int i=0; icheck(); const char *mpoint = e->getmpoint(); if (strcmp(mpoint,"/")==0){ // fixroot (e,status); }else if (strcmp(mpoint,"/proc")==0){ proc_seen = true; }else if (e->is_swap()){ swap_seen = true; }else if (strcmp(e->getcomment(),NO_SWAP_NEEDED)==0){ no_swap_seen = true; } } if (!proc_seen){ status.append(MSG_U(N_PROCADD ,"An entry for the /proc file system" " has been added\n" "The proc file system is needed for quite a few\n" "system utilities such as \"ps\"\n\n")); add (new FSTAB_ENTRY("none /proc proc defaults")); } if (!swap_seen && !no_swap_seen){ if (dialog_yesno (MSG_U(T_NOSWAP,"No swap !!!") ,MSG_U(Q_NOSWAP,"Your linux system is lacking\n" "a swap file or swap partition\n" "\n" "This is a severe weakness\n" "Do you want to create a swap now ?") ,help_swap) == MENU_YES){ edit (FSTAB_ENTRY_SWAP); }else if (dialog_yesno(MSG_U(T_AREYOUSURE,"Are you sure") ,MSG_U(Q_BUGYOU,"I will bug you about your system\n" "lacking a swap every time I can\n" "\n" "Do you want me to shut off ?") ,help_swap) == MENU_YES){ add (new FSTAB_ENTRY(NO_SWAP_NEEDED)); } } if (status.is_filled()){ xconf_notice(MSG_U(N_SOMEMODS ,"Some ajustements were made to the /etc/fstab\n" "\n" "%s"),status.get()); } } void fstab_check() { FSTAB fstab; fstab.check(); if (fstab.was_modified()) fstab.write(); }