#include #include #include #include #include /* for mkstemp(), etc */ #include /* for symlink() */ #include "../custom.h" #include "shared_lock.h" /* for get_shared_lock() , etc */ #include "shared_util.h" /* for cs_critical_error */ #include "shared_news_util.h" /* for remove_stale_symlinks() */ #include "shared_file_util.h" #include "shared_cs_util.h" #include "shared_bb_manifest.h" /** Reads the info file, that is, the file named info_fname in *** sender_username's "assignments" directory. *** Returns source_path, which is the path to the XML quiz file *** and dirname, which is the name of the directory (within *** sender_username's "assignments" directory) where the source file *** can be found. *** *** dirname is later used to create a symbolic link **/ void get_hotpot_exam_source_fname (char *source_path, char *dirname, const char *course_path, const char *sender_username, const char *info_fname) { char infopath[MAX_PATH + 1]; NEWS_INFO info; ATTACHMENT attach; FILE *fp; int fd; snprintf (infopath, MAX_PATH + 1, "%speople/%s/%s/%s", course_path, sender_username,ASSIGNMENTS_DIR, info_fname); fp = fopen (infopath, "r"); if (!fp) cs_critical_error (ERR_FOPEN_READ_FAILED, ""); fd = fileno(fp); get_shared_lock(fd,1); /*shared_lock.c */ if (fread (&info, sizeof (NEWS_INFO), 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, ""); if(info.attachments != -1) cs_critical_error( ERR_EXPECTED_ATTACHED_WEBSITE , ""); if (fread (&attach, sizeof (ATTACHMENT), 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, ""); release_lock(fd); /* shared_lock.c */ fclose (fp); strncpy (dirname, attach.unique_fname, MAX_FILENAME + 1); /* unique_fname contains the name of the directory */ snprintf(source_path,MAX_PATH+1, "%speople/%s/%s/%s/%s", course_path,sender_username,ASSIGNMENTS_DIR, attach.unique_fname, attach.orig_fname); } /** writes to 'path' the full path to username's score file for the ** hotpotatoes exam sent by 'sender' represented by 'info_fname' **/ void get_hotpot_score_path(const char *course_path, const char *username, const char *sender, const char *info_fname, char *path) { snprintf(path,MAX_PATH + 1, "%s%s/%s/%s/%s_%s%s",course_path, PEOPLE_DIR, username, ASSIGNMENTS_DIR,sender,info_fname, HOTPOT_EXAM_SCORE_EXTENSION); } time_t hotpot_time_viewed(const char *score_path) { FILE *fp; int fd; time_t viewed_time; fp = fopen(score_path,"r"); if(!fp) return 0; fd = fileno(fp); get_shared_lock(fd,1); /* shared_lock.c */ if(fread(&viewed_time, sizeof(time_t), 1, fp) != 1) viewed_time = 0; release_lock(fd); fclose(fp); return viewed_time; } int get_hotpot_unique_fd(const char *base_dir, const char *filetype, char *unique_fname, time_t *time_sent) { char template[MAX_PATH + 1]; char timestring[MAX_TIMESTRING + 1]; int fd; char *ptr; strftime (timestring, MAX_TIMESTRING, "%m%d%Y%H%M%S",localtime (time_sent)); snprintf (template, MAX_PATH + 1, "%s%s_%s_XXXXXX", base_dir,filetype, timestring); fd = mkstemp(template); if(fd == -1) cs_critical_error(ERR_MKSTEMP_FAILED, ""); change_mkstemp_permission(template); /*shared_file_util.c */ ptr = strrchr(template,'/'); if(!ptr) cs_critical_error(ERR_GENERAL_ERROR, ""); ptr++; strncpy(unique_fname, ptr,MAX_FILENAME + 1); if(fchmod(fd,S_IWGRP|S_IRGRP|S_IRUSR|S_IWUSR)) cs_critical_error(ERR_CHMOD_FAILED,""); return fd; } void get_hotpot_unique_fname(char *unique_fname, const char *base_dir, const char *filetype, time_t *time_sent) { int fd; fd = get_hotpot_unique_fd(base_dir, filetype, unique_fname, time_sent); close(fd); } /* retrieves, in 'value' item 'n' from ** the comma separated value line 'line' ** the value can't exceed maxlen ** 'n' starts from 0 as the first item */ int csv_value(char *line, int n, char *value, int maxlen) { char *start_ptr, *end_ptr = 0, *null_ptr; char tmp; int is_quoted; int count, end_found; for(count = 0; count <= n; count++) { start_ptr = !count? line : end_ptr + 1; if((!*start_ptr) || (*start_ptr == '\n') || (*start_ptr == '\r')) return 1; /* item not found */ is_quoted = ( *start_ptr == '"'); for(end_ptr = start_ptr + 1, end_found=0; !end_found && *end_ptr; end_ptr++) { switch(*end_ptr) { case '\0': case '\n': case '\r': if(is_quoted) return 1; else end_found = 1; break; case ',': end_found = !is_quoted || (is_quoted && (*(end_ptr - 1) == '"')); break; default: break; } } if(!end_found) return 1; end_ptr--; if(end_ptr < line) return 1; /* null_ptr used to strip quotes from quoted values */ null_ptr = is_quoted? end_ptr -1 : end_ptr; tmp = *null_ptr; *null_ptr = '\0'; strncpy(value,is_quoted?start_ptr + 1: start_ptr,maxlen); *null_ptr = tmp; } return 0; } void create_hotpot_exam_symlink (const char *coursepath, const char *sender, const char *dirname, const SESSION *user, const char *crs, char *symlink_fname, int access) { char oldname[MAX_PATH + 1]; char newname[MAX_PATH + 1]; char manifest[MAX_PATH + 1]; struct stat buffer; char *base =0; snprintf (manifest, MAX_PATH + 1, "%s%s/%s/%s/%s/%s", coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname, "imsmanifest.xml"); if( !stat(manifest, &buffer)) base = get_bb_image_base(manifest); /* shared_bb_manifest.c */ /* oldname must be expressed relative to the images/links directory ** thus, the leading ../ */ if(base) { snprintf (oldname, MAX_PATH + 1, "../%s%s/%s/%s/%s/%s/", coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname, base); free(base); } else snprintf (oldname, MAX_PATH + 1, "../%s%s/%s/%s/%s", coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname); get_symlink_fname(crs, symlink_fname, user); /* shared_util.c */ /* note next that the path for 'newname' is relative to the bin directory */ snprintf (newname, MAX_PATH + 1, "../images/links/%s", symlink_fname); remove_stale_symlinks (user->username, crs, access); /* shared_news_util.c */ if (symlink (oldname, newname)) cs_critical_error (ERR_SYMLINK_FAILED, ""); }