home_etc STRIKES BACK

Rafal Cygnarowski zswi w pers.pl
Czw, 6 Cze 2002, 08:10:39 CEST


W liście z czw, 06-06-2002, godz. 02:33, Łukasz J. Mozer pisze: 
> Witaj Tomek,
> Dnia 6 czerwca 2002, o 01:05 napisałeś:
> 
> > 3. Czy istnieje katalog $HOME/$CONFIG_DIR ?
> 
> I żeby nie było wpadek - czy możemy do niego zapisywać.

I czy $HOME jest napewno nasz $HOME, i czy $CONFIG_DIR nie zawiera nie
wlasciwych znakow, i czy $HOME nie zawiera nie wlasciwych znakow i czy
$CONFIG_DIR nie jest ustawione na obrazliwe okreslenia typu D... qr...
itd itp... 

LUDZIE! nie popadajmy w paranoje! Sprawdzcie ile z tych programow, ktore
sa do poprawienia sprawdza czy $HOME istnieje. Ile z nich sprawdza czy
moze do niego zapisywac. Ile z nich sprawdza cokolwiek! Zdazaja sie
takie co nie sprawdzaja bledow z write()! Prawda jest taka, ze program
powinien robic to co wynika z konfiguracji systemu. Wezmy prosty
przyklad:

Jest program nie przerobiony, ktory zaklada katalog konfiguracyjny w
$HOME/.program a w nim swoje pliki, np. plik_programu.
Schemat dzialania takiego programu to z reguly cos takiego:

//--------------------------------------------------------------------
#define PROGRAM_DIR ".program/"
#define PROGRAM_FILE "plik_programu";

int main (int argc, char *argv[]) {
	char *buf;
	char *program_dir;
	char *config_file;
	int fd;

	buf = getenv("HOME");
	if (buf == NULL) {
		printf("nie ma $HOME nie wiem gdzie pisac!\n"); 
		return -1;
	}

	config_dir = (char*)malloc(strlen(buf)
		+ strlen(PROGRAM_DIR) + 2);

	if (!config_dir) { 
		printf("Blad alokacji pamieci!\n");
		return -1; 
	}

	strcopy(config_dir, buf);
	strcat(config_dir, "/");
	strcat(config_dir, PROGRAM_DIR);
	if (-1 == mkdir(config_dir, 0700)) {
		printf("Nie moge utworzyc katalogu %s\n", config_dir);
		return -1;
	}

	config_file = (char*)malloc(strlen(buf)
		+ strlen(PROGRAM_DIR) + strlen(PROGRAM_FILE) + 3);
	if (!cofnig_file) {
		printf("Blad alokacji pamieci");
		return -1;
	}
	strcopy(config_file, config_dir);
	strcopy(config_file, PROGRAM_FILE);
	
	fd = open(config_file, O_CREATE);
	if (fd == -1) {
		printf("Nie moglem utworzyc pliku %s\n", config_file);
		return -1;
	}

	/*
	 *  I tutaj pozostaly stuff z programu....
 	 */

	return 0;
}

//--------------------------------------------------------------------

Zauwazcie, ze program zachowa sie poprawnie, jezeli do config_dir dolozy
sie $CONFIG_DIR (oczywiscie jesli zmienna istnieje). Dodatkowo nasuwa
sie tylko pytanie co jesli $CONFIG_DIR jest puste? a no po prostu NIC!
Skad wiecie, ze uzytkownik nie chce miec plikow konfiguracyjnych w
$HOME, tyle ze bez kropek???

IMVHO program nie moze sprawdzac nic ponad to co sprawdzal do tej pory.
Bo i po co ma to robic? Przeciez to co najwazniesze caly czas jest
sprawdzane: czy udalo sie utworzyc katalog, czy udalo sie stworzyc plik,
czy udalo sie zapisac do pliku. W kazdym z tych przypadkow podejmuje w
razie bledu akcje wlasciwa dla samego siebie. Sprawdzanie chorych
sytuacji nie ma sensu! Zawsze znajdzie sie powod dla ktorego plik nie
moze byc zapisany! Np. $HOME bedzie na innym volumenie niz $HOME/etc i
akurat ten drugi bedzie juz pelny.. i co? i powinien brac z tego powodu
konfiguracje z $HOME??????!!!! NIE! Nie tedy droga... no rozpatrzmy i
ten przypadek... wolumen jest pelny... uzytkownik probuje zapisac
konfiguracje ale dostaje tylko komunikat o bledzie, ze to nie mozliwe...
i co? stala sie tragedia? Operacje powinny byc ATOMOWE a nie prowadzic
do sytacji gdy wypadaloby napisac ponizszy komunikat o bledzie:

	Drogi uzytkowniku! Miales ustawiana zmienna $CONFIG_DIR
	ale nie	bylo tam katalogu do konfiguracji. Probowalem
	zapisac	konfiguracje do $HOME, ale i to nie zakonczylo
	sie powodzeniem. Dlatego podjalem probe utowrzenia
	katalogu $CONFIG_DIR co zakonczylo sie powodzeniem, ale
	pliku juz mi sie nie udalo w tym katalogu utworzyc!
	No sorry...w tej sytuacji wychodze...

Zastanowcie sie czy warto zajmowac sie sytuacja inna niz sprawdzaniem
czy getenv("CONFIG_DIR") zwraca NULL czy nie. Pamietajcie tez, ze:
1. ustawianie CONFIG_DIR to nie tylko zadanie administratora
2. to administrator systemu podejmuje dzialanie odpowiednie do jego
sytuacji (do tego zalicza sie tez sposob rozwiazania problemu w
zaleznosci od wielkosci administrowanego systemu)
3. zmienna CONFIG_DIR w dystrybucji domyslnie nie powinna byc nigdzie
ustawiana. Na cos takiego bedzie mozna sobie pozwolic, gdy stosowanie
zmiennej $CONFIG_DIR stanie sie powszechne.

pozdrawiem,
pascalek

-- 
Rafal Cygnarowski
rafi w pers.pl




Więcej informacji o liście dyskusyjnej pld-devel-pl