/*************************************************************************** * Copyright (C) 2006 by couriousous, blino, trem * * couriousous@mandriva.org * * oblin@mandriva.com * * trem@mandriva.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "prcsys.h" #include "prcsys_files.h" #include "prcsys_list.h" #include "prcsys_action.h" #include "prcsys_log.h" /** * This function return the list of all files in a directory * argument: * - dir : directory name * return: * - a malloced array of file found in the directory * */ char ** list_files(char * dir) { struct dirent **namelist; int n; int i = 0; char ** templist; n = scandir(dir, &namelist, NULL, alphasort); if (n < 0) return NULL; else if(n == 0) { free(namelist); return NULL; } else { malloc_or_die(templist, n * sizeof(char *) + 1); while(n--) { struct stat buf; char buffer[1024]; /* path are never > 255 */ snprintf(buffer,sizeof(buffer),"%s/%s",dir,namelist[n]->d_name); /* get information about this file */ if(stat(buffer, &buf) != 0){ printandlog("Cannot stat %s\n",buffer); free(namelist[n]); continue; } /* if (not a regular file OR first letter of the name != mode) */ if(!S_ISREG(buf.st_mode) || namelist[n]->d_name[0] != mode) { free(namelist[n]); continue; } malloc_or_die(templist[i],strlen(buffer) + 1 /* \0 */ ); strcpy(templist[i],buffer); i++; free(namelist[n]); } /* end flag */ templist[i] = NULL; free(namelist); } return templist; } /** * This function open a file and return a pointer to the flux * argument: * - path : filename with path * return: * - pointer to flux * note: * - exit if the file can't be opened * */ FILE *open_file(char * path) { FILE * file; if((file = fopen(path,"r")) == NULL) { printandlog("Cannot scan %s: %s\n",path,strerror(errno)); exit(1); } return file; } /** * This function close a file * argument: * - file : pointer to the flux to close * - path : filename with path * return: * - nothing * note: * - exit if the file can't be opened * */ void close_file(FILE *file, char * path) { if (fclose(file) == EOF) { printandlog("Cannot close %s: %s\n",path,strerror(errno)); exit(1); } } /** * This function check is the service contain a tag * argument: * - filename (with path) * - tag to look for * return: * - 0 => no (this file don't contain this tag) * - 1 => yes * */ int check_prcsys_tag(char * path, const char * tag) { FILE * file; char buffer[1024]; int found = 0; file = open_file(path); while(fgets(buffer,sizeof(buffer),file) != NULL) { if(strncmp(tag,buffer,strlen(tag)) == 0) { found = 1; break; } } close_file(file, path); return found; } #define LSB_OPEN_TAG "### BEGIN INIT INFO" #define LSB_CLOSE_TAG "### END INIT INFO" /** * This function check if the file given as parameter is a LSB script * ie: there is an "INIT INFO" section * argument: * - filename (with path) * return: * 0 => not an LSB script * 1 => LSB script * */ int check_lsb_script(char * path) { FILE * file; char buffer[1024]; int lsb_open_found = 0; file = open_file(path); while(fgets(buffer,sizeof(buffer),file) != NULL){ if(!lsb_open_found && strncmp(LSB_OPEN_TAG,buffer,strlen(LSB_OPEN_TAG)) == 0) lsb_open_found = 1; if(lsb_open_found && strncmp(LSB_CLOSE_TAG,buffer,strlen(LSB_CLOSE_TAG)) == 0) { lsb_open_found++; break; } } close_file(file, path); return (lsb_open_found == 2) ? 1 : 0; } /** * This function read the file given as parameter until * the tag LSB_OPEN_TAG is reach. * ie: go to the LSB_OPEN_TAG * argument: * - file : file to read (file should be already open) * return: * - nothing, but the position in the file is after LSB_OPEN_TAG * */ void goto_lsb_tag(FILE * file) { char buffer[1024]; while(fgets(buffer,sizeof(buffer),file) != NULL) { if(strncmp(LSB_OPEN_TAG,buffer,strlen(LSB_OPEN_TAG)) == 0) { break; } } } /** * This function fills the buf with the argument found for keywords * in info section * argument: * - buf : buffer to fill * - buflen : max size of buf * - file : file to read (pointer to flux) * - keywords : keywords to read * return: * - buf is filled * */ void fill_buf_with_argument(char * buf, int buflen, FILE * file, char * keywords) { char buffer[1024]; int size_keywords = strlen(keywords); /* go to the beginning of the file */ (void)fseek(file, 0L, SEEK_SET); /* go to the info section */ goto_lsb_tag(file); /* by default, nothing */ buf[0] = '\0'; /* search keywords */ while(fgets(buffer, sizeof(buffer), file) != NULL) { if(strncmp(LSB_CLOSE_TAG, buffer, strlen(LSB_CLOSE_TAG)) == 0) /* no # Provides ?!? */ break; if(strncmp(keywords, buffer, size_keywords) == 0) { strncpy(buf, buffer + size_keywords, buflen); break; } } } #define LSB_PROVIDES_TAG "# Provides:" /** * This function search and read the provide line in a file * argument: * - filename (with path) * - buf : buffer to fill with provide * - buflen : the max size of the previous buffer * return: * - buf is filled (is provide is found) * */ void parse_file_provide_lsb(char * path,char * buf,int buflen) { FILE * file; file = open_file(path); fill_buf_with_argument(buf, buflen, file, LSB_PROVIDES_TAG); close_file(file, path); } #define LSB_REQUIRES_TAG1_START "# Required-Start:" #define LSB_REQUIRES_TAG2_START "# Should-Start:" #define LSB_REQUIRES_TAG1_STOP "# Required-Stop:" #define LSB_REQUIRES_TAG2_STOP "# Should-Stop:" /** * This function search and read the requires line in a file. * argument: * - filename (with path) * - buf : buffer to fill with requires * - buflen : the max size of buf * return : * - buf is filled with requires (if found) * */ void parse_file_dep_lsb(char * path, char * buf, int buflen) { FILE * file; char temp_dep[2][buflen]; *buf = '\0'; file = open_file(path); if(mode == MODE_START) { fill_buf_with_argument(temp_dep[0], buflen, file, LSB_REQUIRES_TAG1_START); fill_buf_with_argument(temp_dep[1], buflen, file, LSB_REQUIRES_TAG2_START); } else { fill_buf_with_argument(temp_dep[0], buflen, file, LSB_REQUIRES_TAG1_STOP); fill_buf_with_argument(temp_dep[1], buflen, file, LSB_REQUIRES_TAG2_STOP); } close_file(file, path); snprintf(buf,buflen,"%s %s", temp_dep[0], temp_dep[1]); } /** * This function check if the "subsys" subsystem is already up * ie: if the file /var/lock/subsys/ exist OR * if the file /var/lock/subsys/.init exist * argument: * - subsys : name of the subsys to check * return: * - 0 => subsys is down * - 1 => subsys is up * */ int subsys_already_up(char * subsys) { char file[255]; struct stat sbuf; if(test_mode) return mode == MODE_START ? 0 : 1; snprintf(file,sizeof(file),"/var/lock/subsys/%s",subsys); if(!stat(file,&sbuf)) return 1; snprintf(file,sizeof(file),"/var/lock/subsys/%s.init",subsys); if(!stat(file,&sbuf)) return 1; return 0; }