1 #ifndef lint 2 static char sccsid[] = "@(#)selsub.c 4.6 (Berkeley) 05/10/89"; 3 #endif not lint 4 5 #include <sys/types.h> 6 #include <sys/file.h> 7 #include <sys/stat.h> 8 #include <stdio.h> 9 #include "lrnref.h" 10 #include "pathnames.h" 11 12 char learnrc[100]; 13 14 selsub(argc,argv) 15 char *argv[]; 16 { 17 char ans1[100]; 18 static char ans2[40]; 19 static char dirname[40]; 20 static char subname[40]; 21 FILE *fp; 22 char *getenv(); 23 char *home; 24 25 if (argc > 1 && argv[1][0] == '-') { 26 direct = argv[1]+1; 27 argc--; 28 argv++; 29 } 30 if (chdir(direct) != 0) { 31 perror(direct); 32 fprintf(stderr, "Selsub: couldn't cd to non-standard directory\n"); 33 exit(1); 34 } 35 sname = argc > 1 ? argv[1] : 0; 36 if (argc > 2) { 37 strcpy (level=ans2, argv[2]); 38 if (strcmp(level, "-") == 0) /* no lesson name is - */ 39 ask = 1; 40 else if (strcmp(level, "0") == 0) 41 level = 0; 42 else 43 again = 1; /* treat as if "again" lesson */ 44 } 45 else 46 level = 0; 47 if (argc > 3 ) 48 speed = atoi(argv[3]); 49 if ((home = getenv("HOME")) != NULL) { 50 sprintf(learnrc, "%s/.learnrc", home); 51 if ((fp=fopen(learnrc, "r")) != NULL) { 52 char xsub[40], xlev[40]; int xsp; 53 fscanf(fp, "%s %s %d", xsub, xlev, &xsp); 54 fclose(fp); 55 if (*xsub && *xlev && xsp >= 0 /* all read OK */ 56 && (argc == 2 && strcmp(sname, xsub) == 0 57 || argc <= 1)) { 58 strcpy(sname = subname, xsub); 59 strcpy(level = ans2, xlev); 60 speed = xsp; 61 again = 1; 62 printf("[ Taking up where you left off last time: learn %s %s.\n", 63 sname, level); 64 printf("%s\n \"rm $HOME/.learnrc\", and re-enter with \"learn %s\". ]\n", 65 " To start this sequence over leave learn by typing \"bye\", then", 66 sname); 67 } 68 } 69 } 70 if (!sname) { 71 printf("These are the available courses -\n"); 72 list("Linfo"); 73 printf("If you want more information about the courses,\n"); 74 printf("or if you have never used 'learn' before,\n"); 75 printf("press RETURN; otherwise type the name of\n"); 76 printf("the course you want, followed by RETURN.\n"); 77 fflush(stdout); 78 if (gets(sname=subname) == NULL) 79 exit(0); 80 if (sname[0] == '\0') { 81 list("Xinfo"); 82 do { 83 printf("\nWhich subject? "); 84 fflush(stdout); 85 if (gets(sname=subname) == NULL) 86 exit(0); 87 } while (sname[0] == '\0'); 88 } 89 } 90 chknam(sname); 91 total = cntlessons(sname); 92 if (!level) { 93 printf("If you were in the middle of this subject\n"); 94 printf("and want to start where you left off, type\n"); 95 printf("the last lesson number the computer printed.\n"); 96 printf("If you don't know the number, type in a word\n"); 97 printf("you think might appear in the lesson you want,\n"); 98 printf("and I will look for the first lesson containing it.\n"); 99 printf("To start at the beginning, just hit RETURN.\n"); 100 fflush(stdout); 101 if (gets(ans2) == NULL) 102 exit(0); 103 if (ans2[0]==0) 104 strcpy(ans2,"0"); 105 else 106 again = 1; 107 level=ans2; 108 getlesson(); 109 } 110 111 /* make new directory for user to play in */ 112 if (chdir(_PATH_TMP) != 0) { 113 perror(_PATH_TMP); 114 fprintf(stderr, "Selsub: couldn't cd to public directory\n"); 115 exit(1); 116 } 117 sprintf(dir=dirname, "pl%da", getpid()); 118 sprintf(ans1, "mkdir %s", dir); 119 system(ans1); 120 if (chdir(dir) < 0) { 121 perror(dir); 122 fprintf(stderr, "Selsub: couldn't make play directory with %s.\nBye.\n", ans1); 123 exit(1); 124 } 125 /* after this point, we have a working directory. */ 126 /* have to call wrapup to clean up */ 127 (void)sprintf(ans1, "%s/%s/Init", direct, sname); 128 if (access(ans1, R_OK)==0) { 129 (void)sprintf(ans1, "%s/%s/Init %s", direct, sname, level); 130 if (system(ans1) != 0) { 131 printf("Leaving learn.\n"); 132 wrapup(1); 133 } 134 } 135 } 136 137 chknam(name) 138 char *name; 139 { 140 if (access(name, 05) < 0) { 141 printf("Sorry, there is no subject or lesson named %s.\nBye.\n", name); 142 exit(1); 143 } 144 } 145 146 #ifndef DIR 147 #include <sys/dir.h> 148 #endif 149 150 cntlessons(sname) /* return number of entries in lesson directory; */ 151 char *sname; /* approximate at best since I don't count L0, Init */ 152 { /* and lessons skipped by good students */ 153 #if BSD4_2 154 struct direct dbuf; 155 register struct direct *ep = &dbuf; /* directory entry pointer */ 156 int n = 0; 157 DIR *dp; 158 159 if ((dp = opendir(sname)) == NULL) { 160 perror(sname); 161 wrapup(1); 162 } 163 for (ep = readdir(dp); ep != NULL; ep = readdir(dp)) { 164 if (ep->d_ino != 0) 165 n++; 166 } 167 closedir(dp); 168 return n - 2; /* minus . and .. */ 169 #else 170 struct stat statbuf; 171 172 stat(sname, &statbuf); 173 return statbuf.st_size / 16 - 2; 174 #endif 175 } 176