#include #include /* for free() */ #include #include #include #include #include /* for exec(), wait() et. al */ #include #include "global.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_news_util.h" static void read_parameters (char *course, char *key, char *sender, char *dir, int *grp) { char intstring[20]; cs_get_required_parameter ("crs", course, MAX_FILENAME); /* shared_cgi_util.c */ cs_get_required_parameter ("id", key, MAX_KEY); cs_get_required_parameter ("sender", sender, MAX_USERNAME); cs_get_required_parameter ("dir", dir, MAX_FILENAME); cs_get_required_parameter ("grp", intstring, 5); *grp = atoi (intstring); } static void deliver_file (char *mime_type, char *source_file, char *dest_file) { #define CHUNKSIZE 8192 FILE *fp; struct stat buf; int bytes_read; int bytes_left; char buffer[CHUNKSIZE]; if (stat (source_file, &buf)) cs_critical_error (ERR_STAT_FAILED, ""); fp = fopen (source_file, "r"); if (!fp) cs_critical_error (ERR_FOPEN_READ_FAILED, ""); printf ("Content-type:%s\n", mime_type); printf ("Content-disposition: filename=\"%s\"\n", dest_file); printf ("Content-length: %ld\n\n", (long) buf.st_size); bytes_left = buf.st_size; bytes_read = CHUNKSIZE; while (bytes_left) { if (bytes_left < CHUNKSIZE) bytes_read = bytes_left; if (fread (buffer, bytes_read, 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, ""); bytes_left -= bytes_read; if (fwrite (buffer, bytes_read, 1, stdout) != 1) cs_critical_error (ERR_FWRITE_FAILED, ""); } fclose (fp); #undef CHUNKSIZE } static void check_zip_status (int error) { switch (error) { /* this is my error code if exec() failed */ case 88: cs_critical_error (ERR_CANT_START_ZIP, ""); break; /* remaining errors reported by unzip */ case 0: break; /* everything went OK */ case 2: cs_critical_error (ERR_ZIP_ERROR_CODE_2, ""); break; case 3: cs_critical_error (ERR_ZIP_ERROR_CODE_3, ""); break; case 4: cs_critical_error (ERR_ZIP_ERROR_CODE_4, ""); break; case 5: cs_critical_error (ERR_ZIP_ERROR_CODE_5, ""); break; case 6: cs_critical_error (ERR_ZIP_ERROR_CODE_6, ""); break; case 7: cs_critical_error (ERR_ZIP_ERROR_CODE_7, ""); break; case 8: cs_critical_error (ERR_ZIP_ERROR_CODE_8, ""); break; case 9: cs_critical_error (ERR_ZIP_ERROR_CODE_9, ""); break; case 10: cs_critical_error (ERR_ZIP_ERROR_CODE_10, ""); break; case 11: cs_critical_error (ERR_ZIP_ERROR_CODE_11, ""); break; case 12: cs_critical_error (ERR_ZIP_ERROR_CODE_12, ""); break; case 13: cs_critical_error (ERR_ZIP_ERROR_CODE_13, ""); break; case 14: cs_critical_error (ERR_ZIP_ERROR_CODE_14, ""); break; case 15: cs_critical_error (ERR_ZIP_ERROR_CODE_15, ""); break; case 16: cs_critical_error (ERR_ZIP_ERROR_CODE_16, ""); break; case 18: cs_critical_error (ERR_ZIP_ERROR_CODE_18, ""); break; default: cs_critical_error (ERR_ZIP_ERROR_UNDOCUMENTED, ""); break; } } static void do_zip (const char *zipfile, const char *zip_program) { pid_t pid, status; if ((pid = fork ()) < 0) cs_critical_error (ERR_CANT_START_NEW_PROCESS, ""); if (pid == 0) { /* child process */ execl (zip_program, "zip", "-r", "-q", zipfile, ".", (char *) 0); exit (88); /* this is returned if above execl() fails */ } /*** parent process */ while (wait (&status) != pid); check_zip_status (WEXITSTATUS (status)); /* report on status */ } static void send_zipped_website(const char *course, const char *key, const char *sender, const char *dir, int grp, CONFIG_STRUCT *conf, SESSION *user) { char website_path[MAX_PATH + 1]; char zipfile[MAX_PATH + 1]; char zipfile_fullname[MAX_PATH + 1]; char current_dir[MAX_PATH + 1]; char zip_program_fullname[MAX_PATH + 1]; char modified_course[MAX_PATH + 1]; course_slash_to_dot(course, modified_course); /* shared_util.c */ /* get full path to 'bin' directory */ if(!getcwd(current_dir,MAX_PATH)) cs_critical_error(ERR_GETCWD_FAILED,""); if(grp == CLIPBOARD) snprintf(website_path, MAX_PATH + 1,"%s%s/%s", CLIPBOARD_PATH, user->id, dir); else { set_discussion_names (conf->course_path, sender, grp); /* shared_news_util.c */ snprintf (website_path, MAX_PATH + 1, "%s/%s", discussion_path, dir); /* discussion_path global in shared_news_util.c */ } /* put the zipfile in the distribution's 'tmp' directory */ snprintf(zipfile, MAX_PATH + 1, "%s/../tmp/%s_%s", current_dir,sender,modified_course); snprintf(zipfile_fullname, MAX_PATH + 1, "%s.zip",zipfile); snprintf(zip_program_fullname,MAX_PATH + 1, "%s/%s",current_dir,ZIP_PATH); if (chdir (website_path)) cs_critical_error (ERR_CHDIR_FAILED, ""); unlink(zipfile_fullname); do_zip(zipfile_fullname,zip_program_fullname); deliver_file("application/zip", zipfile_fullname, ZIPPED_WEBSITE_FNAME); unlink(zipfile_fullname); } int main (void) { char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ char sender[MAX_USERNAME + 1]; /* from user=? command line */ char dir[MAX_FILENAME + 1]; /* from dir=? cmd line */ int grp; /* from optional grp=? cmd line */ SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ cs_cgi_init(); read_parameters (course, key, sender, dir, &grp); read_configuration_file (course, &conf); /* shared_util.c */ validate_key (key, &user, &conf); /* shared_util.c */ if (user.group != FACULTY) cs_critical_error (ERR_REQUEST_DENIED, ""); send_zipped_website(course,key,sender,dir,grp, &conf, &user); cs_cgi_destroy(); return 0; }