#include #include #include #include #include #include #include #include #include #include void dump (char * buf, int len) { int i, ret; for (i=0; i> 3) & 7; outbuf[2] += (val >> 6) & 7; ret = write (1, outbuf, 5); } if (ret < 0) { perror ("write"); return; } } } void scan () { DIR * d = opendir ("."); struct dirent * dent; struct stat stat; static char buf[1000]; char dstname[100]; int ret, src, dst, fd, more; /* Nachsehen, ob wir das aktuelle Verzeichnis oeffnen konnten. */ if (!d) { perror ("opendir"); return; } /* Alle Eintraege im aktuellen Verzeichnis durchgehen. */ while ((dent = readdir (d))) { int i; /* "." ist das aktuelle Verzeichnis und wird ignoriert, */ if (strcmp (dent->d_name, ".") == 0) continue; /* genauso wie ".." */ if (strcmp (dent->d_name, "..") == 0) continue; /* Dateien, die nur aus isgraph-Zeichen bestehen * werden uebersprungen, also: Erstes Zeichen suchen, * das kein "graph" ist... */ for (i=0; dent->d_name[i] && isgraph ((int)dent->d_name[i]); ++i); /* Wenn das das Nullbyte war, dann wird die Datei * uebersprungen */ if (dent->d_name[i] == 0) continue; /* Name ausgeben */ dump (dent->d_name, strlen (dent->d_name)); /* Aktionen durchfuehren, more gibt an, ob fuer diese Datei * noch nach weitern Aktionen gefragt werden soll. */ more = 1; while (more) { char ch; /* Read an action. */ if (read (0, &ch, 1) < 0) { perror ("read"); return; } switch (ch) { case 'a': /* Abbrechen */ return; case 'n': /* Naechste Datei */ more = 0; break; case 'd': /* Loeschen und auf zur naechsten Datei */ if (unlink (dent->d_name) < 0) perror ("unlink"); else more = 0; break; case 's': /* Erste 1000 Zeichen anzeigen. */ /* Datei oeffnen. */ fd = open (dent->d_name, O_RDONLY); if (fd < 0) { perror ("open"); break; } /* Bis zu 1000 Zeichen lesen. */ ret = read (fd, buf, 1000); /* Datei schliessen. */ close (fd); if (ret < 0) { perror ("read"); break; } /* Gelesene Zeichen ausgeben. */ dump (buf, ret); break; case 'c': /* Quelldatei oeffnen */ src = open (dent->d_name, O_RDONLY); if (src < 0) { perror ("open"); break; } /* Dateiinformationen herausfinden. */ if (fstat (src, &stat) < 0) { perror ("fstat"); close (src); break; } /* Nichtregulaere Dateien werden * uebersprungen. */ if ((stat.st_mode & S_IFMT) != S_IFREG) { write (1, "failed\n", 7); continue; } /* Dateiname fuer Zieldatei */ sprintf (dstname, "%d", (int)stat.st_ino); /* Zieldatei oeffnen. Schlaegt fehl, wenn die * Datei bereits existiert. */ dst = open (dstname, O_WRONLY | O_CREAT | O_EXCL, stat.st_mode & ~S_IFMT); if (dst < 0) { perror ("open"); close (src); break; } /* Dateiinhalt kopieren. */ while (1) { /* Bis zu 1000 Zeichen einlesen */ ret = read (src, buf, 1000); /* Fehler: kopieren abbrechen. */ if (ret < 0) { perror ("read"); break; } /* Dateiende */ if (ret == 0) break; /* Gelesene Zeichen schreiben */ ret = write (dst, buf, ret); if (ret < 0) { perror ("write"); break; } } /* Dateien wieder schliessen. */ close (src); close (dst); break; default: /* Ueberspringen */ break; } } } } /* Hauptprogramm, kurz und knapp. */ int main () { scan (); return 0; }