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